我的数据包含下表:
A B
=== ===
M 2
M 3
M 5
N 5
N 2
O 6
P 13
P 7
P 9
P 11
P 3
现在我需要一个PIVOT(?)查询:
结果将是:
A B1 B2 B3
=== ==== ==== ====
M 2 3 5
N 2 5 null
O 6 null null
P 3 7 9
到目前为止,我一直在尝试使用TOP,GROUP BY,PIVOT创建查询。我认为最好的方法是使用PIVOT,但由于我没有值,我可以用作列名,我被卡住了。此外,对这些值进行前3选择似乎也非常具有挑战性。
*编辑*
它们是A列和B列的唯一约束,因此B的值对于相同的A始终是唯一的。
答案 0 :(得分:7)
你可以使用PIVOT函数来获得结果,但我也会实现类似于row_number()
的窗口函数来获得最终结果。如果您在row_number()
列上对数据进行分区,则B
函数会为每个A
值创建唯一的序列号。此序列号将用作新列名:
select a, B1, B2, B3
from
(
select a, b,
row_number() over(partition by a
order by b) seq
from yourtable
) d
pivot
(
max(b)
for seq in ('1' as B1, '2' as B2, '3' as B3)
) piv;
见SQL Fiddle with Demo。这将得到一个结果:
| A | B1 | B2 | B3 |
|---|----|--------|--------|
| M | 2 | 3 | 5 |
| N | 2 | 5 | (null) |
| O | 6 | (null) | (null) |
| P | 3 | 7 | 9 |
答案 1 :(得分:4)
这是一种适用于Oracle和SQL Server的方法(原始问题已用两个数据库标记)。
您可以使用b
(或a
枚举每个dense_rank()
的{{1}}值,但如果有重复,row_number()
会给出三个不同的值)。然后使用条件聚合进行调整:
dense_rank()
编辑:
如果有重复,该问题不明确该怎么办。例如,如果with ab as (
select a, b,
dense_rank() over (partition by a order by b asc) as seqnum
from t
)
select a,
max(case when seqnum = 1 then b end) as b1,
max(case when seqnum = 2 then b end) as b2,
max(case when seqnum = 3 then b end) as b3
from ab
group by a;
中的数据是1,1,3,3。这应该是三列?
b
或 1,1,2
1, 2, 3
的使用将三个不同的值放入列中(第一个可能的结果)。 dense_rank()
的使用将放置三个最小值(第二个结果)。如果从未有任何重复值,则row_number()
和dense_rank()
会产生相同的结果。