SQL无聚合透视查询问题:同一MarkRange仅返回单个ITEM
解决SQL PIVOT查询中同一分数区间显示多个ITEM的问题
我来帮你搞定这个PIVOT只返回单个ITEM的问题~先理清楚你的场景和需求:
原始数据表(#unw)
| ITEM | MarkRange |
|---|---|
| ENG-MA | 20-39% |
| A1-014 | 40-59% |
| A2-10 | 1-9% |
| 15-69 | 20-39% |
期望的PIVOT结果
| 20-39% | 40-59% | 1-9% |
|---|---|---|
| ENG-MA | A1-014 | A2-10 |
| 15-69 |
你遇到的核心问题是:用MAX(ITEM)做聚合时,同一MarkRange下只会保留一个ITEM,这是因为PIVOT的聚合函数会在单个分组里只取一个聚合后的值,多个ITEM直接被覆盖了。要解决这个问题,我们需要给每个分数区间内的ITEM分配行号,让同一区间的多个ITEM能分布在不同的行中。
修正后的SQL查询
SELECT [20-39%], [40-59%], [1-9%] FROM ( SELECT ITEM, MarkRange, -- 按MarkRange分组,给每个ITEM分配唯一行号 ROW_NUMBER() OVER(PARTITION BY MarkRange ORDER BY ITEM) AS rn FROM #unw ) src PIVOT ( MAX(ITEM) FOR MarkRange IN ([20-39%], [40-59%], [1-9%]) ) piv;
代码逻辑说明
- 添加行号:通过
ROW_NUMBER() OVER(PARTITION BY MarkRange ORDER BY ITEM),给每个MarkRange分组内的ITEM排序并分配行号,同一区间的多个ITEM会被标记为rn=1、rn=2...这样就把同一区间的ITEM拆分成了不同的分组。 - PIVOT聚合:现在PIVOT会基于
rn(隐式分组)进行聚合,每个行号对应的每个MarkRange下只有一个ITEM,所以MAX(ITEM)就能准确取出对应的ITEM,不会再出现覆盖的情况。 - 修正列名:注意你之前的查询里写错了部分区间值(比如把
1-9%写成1.9%),这里要和原始数据的区间值完全匹配,否则会取不到数据。
执行这段代码后,就能得到你想要的结果啦~
内容的提问来源于stack exchange,提问作者Spinx
相关产品推荐
相关产品推荐

