繁体   English   中英

没有已知列名的数据透视

[英]Pivoting without known column name

我有带有数据的下表:

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列分组。
  • 在B列上排序。
  • 从B列中选取最低的3个值。
  • 将这些值放在新的列B1,B2,B3中

因此结果将是:

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,但是由于我没有值可以用作列名,因此我陷入了困境。 同样,对这些值进行前三项选择似乎也很有挑战性。

*编辑*

它们是对列A和B的唯一约束,因此对于相同的A,B的值始终是唯一的。

您可以使用PIVOT函数获取结果,但是我还将实现类似于row_number()的窗口函数以获取最终结果。 如果将数据划分到A列上,则row_number()函数将为每个B值创建一个唯一的序列号。 该序列号将用作新的列名:

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 这将产生结果:

| A | B1 |     B2 |     B3 |
|---|----|--------|--------|
| M |  2 |      3 |      5 |
| N |  2 |      5 | (null) |
| O |  6 | (null) | (null) |
| P |  3 |      7 |      9 |

这是一种适用于Oracle和SQL Server的方法(两个数据库都标记了原始问题)。

您可以使用dense_rank()row_number()枚举每个ab值,但如果有重复项,则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;

编辑:

问题是如果有重复该怎么办尚不清楚。 例如,如果b的数据是b 。那三列应该是哪一列?

1, 2, 3

或1,1,2

使用dense_rank()将三个不同的值放入列中(第一个可能的结果)。 使用row_number()将放置三个最小值(第二个结果)。 如果从不存在任何重复值,那么dense_rank()row_number()产生相同的结果。

暂无
暂无

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

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