[英]Pivoting without known column name
I have the following table with data: 我有带有数据的下表:
A B
=== ===
M 2
M 3
M 5
N 5
N 2
O 6
P 13
P 7
P 9
P 11
P 3
Now I need a PIVOT (?) query to: 现在,我需要一个PIVOT(?)查询来:
So the result will be: 因此结果将是:
A B1 B2 B3
=== ==== ==== ====
M 2 3 5
N 2 5 null
O 6 null null
P 3 7 9
So far I have been trying to create queries with TOP, GROUP BY, PIVOT. 到目前为止,我一直在尝试使用TOP,GROUP BY,PIVOT创建查询。 I think the best way to go is with the PIVOT, but since I do not have a value I can use as a column name, I am stuck.
我认为最好的方法是使用PIVOT,但是由于我没有值可以用作列名,因此我陷入了困境。 Also, making a top-3 selection of these values seems also pretty challenging.
同样,对这些值进行前三项选择似乎也很有挑战性。
* EDIT * *编辑*
Their is a unique constraint on columns A and B, so the values for B are always unique for the same A. 它们是对列A和B的唯一约束,因此对于相同的A,B的值始终是唯一的。
You can use the PIVOT function to get the result, but I would also implement a windowing function similar to row_number()
to get the final result. 您可以使用PIVOT函数获取结果,但是我还将实现类似于
row_number()
的窗口函数以获取最终结果。 The row_number()
function will create a unique sequenced number for each B
value if you partition the data over the A
column. 如果将数据划分到
A
列上,则row_number()
函数将为每个B
值创建一个唯一的序列号。 This sequenced number will be used as the new column names: 该序列号将用作新的列名:
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;
See SQL Fiddle with Demo . 请参阅带有演示的SQL Fiddle 。 This will give a result:
这将产生结果:
| A | B1 | B2 | B3 |
|---|----|--------|--------|
| M | 2 | 3 | 5 |
| N | 2 | 5 | (null) |
| O | 6 | (null) | (null) |
| P | 3 | 7 | 9 |
Here is an approach that works with both Oracle and SQL Server (the original question was tagged with both databases). 这是一种适用于Oracle和SQL Server的方法(两个数据库都标记了原始问题)。
You can just enumerate the b
values for each a
using dense_rank()
(or row_number()
, but dense_rank()
will give three different values if there are duplicates). 您可以使用
dense_rank()
或row_number()
枚举每个a
的b
值,但如果有重复项,则dense_rank()
将给出三个不同的值)。 Then pivot using conditional aggregation: 然后使用条件聚合进行透视:
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;
EDIT: 编辑:
The question is unclear on what to do if there are duplicates. 问题是如果有重复该怎么办尚不清楚。 For instance, if the data in
b
is 1, 1, 2, 3. Which should be the three columns? 例如,如果
b
的数据是b
。那三列应该是哪一列?
1, 2, 3
or 1, 1, 2 或1,1,2
The use of dense_rank()
puts three different values into the columns (the first possible result). 使用
dense_rank()
将三个不同的值放入列中(第一个可能的结果)。 The use of row_number()
would put the three smallest values (the second result). 使用
row_number()
将放置三个最小值(第二个结果)。 If there are never any duplicate values, then dense_rank()
and row_number()
produce the same results. 如果从不存在任何重复值,那么
dense_rank()
和row_number()
产生相同的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.