在一列上使用 'group by' 但获取多列数据

Use 'group by' on one column but get data of multiple columns

您如何设法在一列上创建 'group by' 并仍然在其他列上获取数据(真实数据,而不是 'sum')?

让我举个例子说明我想做什么:

假设 表 A,索引在“Group”上,一个简单的 select * from A 给出:

Group            Album
---------------- ---------------
ABBA             Waterloo
AC/DC            Back in Black
ABBA             Voulez-vous
ABBA             Super Trooper
Imagine Dragons  Night Visions
AC/DC            Highway to Hell
ABBA             The Visitors



我想得到如下最终结果(知道我不能为一个组拥有超过 4 张专辑......我猜现在):

Group            Album1          Album2          Album3          Album4
---------------- --------------- --------------- --------------- ---------------
ABBA             Waterloo        Voulez-vous     Super Trooper   The visitors
AC/DC            Back in Black   Highway to Hell Null            Null
Imagine Dragons  Night Visions   Null            Null            Null



到目前为止,最接近我想要的是如下所示:

select tab4.GROUP,
tab1.ALBUM as PN1,
tab2.ALBUM as PN2,
tab3.ALBUM as PN3,
tab4.ALBUM as PN4
from
(
select A.GROUP, A.ALBUM
from A
where A.ROWID in 
  (select max(ROWID) from A 
  where GROUP in (select GROUP from A A group by A.GROUP having count(*) <= 4)
  group by GROUP
  )
) tab4
left join
(
select A.GROUP, A.ALBUM
from A A
where A.ROWID in 
  (select max(ROWID) from A 
  where GROUP in (select GROUP from A A group by A.GROUP having count(*) <= 3)
  group by GROUP
  )
) tab3 on tab4.GROUP = tab3.GROUP
left join
(
select A.GROUP, A.ALBUM
from A A
where A.ROWID in 
  (select max(ROWID) from A 
  where GROUP in (select GROUP from A A group by A.GROUP having count(*) <= 2)
  group by GROUP
  )
)tab2 on tab4.GROUP = tab2.GROUP
left join
(
select A.GROUP, A.ALBUM
from A A
where A.ROWID in 
  (select max(ROWID) from A 
  where GROUP in (select GROUP from A A group by A.GROUP having count(*) <= 1)
  group by GROUP
  )
) tab1 on tab4.GROUP = tab1.GROUP;


我知道为什么上面的 SQL 请求是错误的:无论抛出 having count(*) 上的什么条件,max(rowid) 都将保持不变。 可能有一些 pivot 可以使用,但我真的不知道如何使用它,因为我只有一个 table 并且需要获取所有数据。

为了更精确,我不需要按特定顺序得到结果 table,我可以将自己限制在 4 张专辑,因为我知道每个 'Group' 不会有更多...但我会喜欢一些通用的东西。



编辑:好吧,似乎我忘记澄清我在 Oracle 10g 上(该死的遗留代码 ^^)所以像 PIVOT 这样的新功能将不起作用。 另外,我不是在寻找像 LISTAGG 这样的字符串聚合,而是在寻找单独的列。

@Alex Poole 说对了:我不仅错过了 10g 中相当于 PIVOT 的代码,而且还错过了 ROW_NUMBER()

所以我的问题的答案如下:

select 
  tab1.group_name,
  MAX(CASE WHEN tab1.rank_number = 1 THEN tab1.album_name ELSE NULL END) AS ALBUM_1,
  MAX(CASE WHEN tab1.rank_number = 2 THEN tab1.album_name ELSE NULL END) AS ALBUM_2,
  MAX(CASE WHEN tab1.rank_number = 3 THEN tab1.album_name ELSE NULL END) AS ALBUM_3,
  MAX(CASE WHEN tab1.rank_number = 4 THEN tab1.album_name ELSE NULL END) AS ALBUM_4
from (
  select group_name, album_name,
    row_number() over (partition by group_name order by album_name) as rank_number
  from tablea
) tab1
group by tab1.group_name;

不确定我的标题是否最适合我遇到的问题,我想我会保持原样,因为它也围绕着 group by

相信这应该适用于 10i:

with r as (
  select
    group_,
    album,
    row_number() over (partition by group_ order by album) r
  from
    tq84_table_a
)
select
  r.group_,
  max(case when r.r=1 then r.album end) album1,
  max(case when r.r=2 then r.album end) album2,
  max(case when r.r=3 then r.album end) album3,
  max(case when r.r=4 then r.album end) album4
from
  r
group by
  r.group_;

我手头没有 10i 安装,现在,所以我无法测试它。