如何设法在一列上创建“分组依据”并仍然获取其他数据(真实数据,而不是“总和”)?
让我举例说明我想做的事情:
假设表A ,“群组”上的索引,简单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请求是错误的:max(rowid)
在having count(*)
被抛出的任何条件下都将保持不变。
可能会有一些pivot
被使用,但我真的不知道如何使用它,因为我只有一个表并且需要获取所有数据。
作为更精确的,我不需要按照特定顺序拥有结果表,我可以将自己限制为4张专辑,因为我知道每个'组'不会超过......但我很欣赏通用的东西。
编辑:好的,似乎我忘了澄清我在使用Oracle 10g(该死的代码^^),因此像PIVOT
这样的新功能将无效。
另外,我不是在寻找像LISTAGG
那样的字符串聚合,而是在寻找单独的列。
答案 0 :(得分:1)
@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
。
答案 1 :(得分:0)
我相信这应该适用于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,所以我无法测试它。