繁体   English   中英

Oracle SQL-将N行的列值转换为1行中的N列

[英]Oracle SQL - Convert N rows' column values to N columns in 1 row

与其他问题(例如“ Oracle将行转换为列”)相比,此方法的窍门是我的列值是任意字符串,而不是我可用于解码的东西。 进行以下查询:

这里的描述表将人们的名字映射到描述,但是每个人可以有多个描述,例如“戴帽子”或“高”。

Select firstName, lastName, 
(Select description from descriptions --This can return any number of rows (0 or more)
 where description.firstName = people.firstName
 and description.lastName = people.lastName
 and rownum <= 3)
from people
where age >= 25;

我想要这样的输出:

FIRSTNAME LASTNAME DESCRIPTION1 DESCRIPTION2 DESCRIPTION3
Jeremy    Smith    Tall         Confused        (null)
Anne      Smith    (Null)       (Null)          (Null)
Mark      Davis    Short        Smart           Strong

在少于3个描述的情况下,我希望在那里为null。 对于3个以上的描述,我只想省略掉。

我正在使用Oracle 11.1。 可以有效地做到这一点吗?

假设您不在乎描述以什么顺序返回(即Jeremy Smith可以正确地将Description1或“ Confused”和Description2为“ Tall”),则只需要对行号进行旋转即可。 如果您关心返回描述的顺序,则可以在ROW_NUMBER分析函数的window函数中添加ORDER BY子句

SELECT firstName, 
       lastName,
       MAX( CASE WHEN rn = 1 THEN description ELSE NULL END ) description1,
       MAX( CASE WHEN rn = 2 THEN description ELSE NULL END ) description2,
       MAX( CASE WHEN rn = 3 THEN description ELSE NULL END ) description3
  FROM (SELECT firstName,
               lastName,
               description,
               row_number() over (partition by lastName, firstName) rn
          FROM descriptions
               JOIN people USING (firstName, lastName)
         WHERE age >= 25)
   GROUP BY firstname, lastname

顺便说一句,我希望您实际上是在存储一个出生日期并计算该人的年龄,而不是存储年龄并假设人们每年都在更新自己的年龄。

我已经尝试过此选项,但是它说我们应该在行分析功能内给出order by子句,如下所示,

row_number() over (partition by lastName, firstName order by lastName, firstName) rn

当我按order by子句时,它对我的​​情况很好用。

我的情况是用户详细信息在表A中,用户组在表C中,并且用户和用户组之间的关联在表B中。一个用户可以有多个用户组。 我需要在一行中包含多个用户组的用户名获得结果

**

查询:

**

SELECT username,
MAX( CASE WHEN rn = 1 THEN ugroup ELSE NULL END ) usergroup1,
MAX( CASE WHEN rn = 2 THEN ugroup ELSE NULL END ) usergroup2,
MAX( CASE WHEN rn = 3 THEN ugroup ELSE NULL END ) usergroup3, 
MAX( CASE WHEN rn = 4 THEN ugroup ELSE NULL END ) usergroup4,
MAX( CASE WHEN rn = 5 THEN ugroup ELSE NULL END ) usergroup5,
from (
select 
a.user_name username, 
c.name ugroup,
row_number() over (partition by a.user_name order by a.user_name) rn
from users a,
usergroupmembership b,
usergroups c
where a.USER_NAME in ('aegreen',
'esportspau'
)
and a.user_id= b.user_id
and b.group_id=c.group_id
)group by uname;

**

查询结果

**

USERNAME    USERGROUP1  USERGROUP2  USERGROUP3  USERGROUP4  USERGROUP5
aegreen US_GOLF (null)  (null)  (null)  (null)
esportspau  EMEA - FSERVICE USER_ES_ES  EMEA-CR-ONLY    (null)  (null)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM