将表格“展平”成单行的最佳方法是什么?
例如,使用下表:
+-----+-------+-------------+------------------+
| Id | hProp | iDayOfMonth | dblTargetPercent |
+-----+-------+-------------+------------------+
| 117 | 10 | 5 | 0.1400 |
| 118 | 10 | 10 | 0.0500 |
| 119 | 10 | 15 | 0.0100 |
| 120 | 10 | 20 | 0.0100 |
+-----+-------+-------------+------------------+
我想制作下表:
+-------+--------------+-------------------+--------------+-------------------+--------------+-------------------+--------------+-------------------+
| hProp | iDateTarget1 | dblPercentTarget1 | iDateTarget2 | dblPercentTarget2 | iDateTarget3 | dblPercentTarget3 | iDateTarget4 | dblPercentTarget4 |
+-------+--------------+-------------------+--------------+-------------------+--------------+-------------------+--------------+-------------------+
| 10 | 5 | 0.14 | 10 | 0.05 | 15 | 0.01 | 20 | 0.01 |
+-------+--------------+-------------------+--------------+-------------------+--------------+-------------------+--------------+-------------------+
我已经设法使用枢轴来做到这一点,然后多次重新加入原始表,但我相当确定有更好的方法。这按预期工作:
select
X0.hProp,
X0.iDateTarget1,
X1.dblTargetPercent [dblPercentTarget1],
X0.iDateTarget2,
X2.dblTargetPercent [dblPercentTarget2],
X0.iDateTarget3,
X3.dblTargetPercent [dblPercentTarget3],
X0.iDateTarget4,
X4.dblTargetPercent [dblPercentTarget4]
from (
select
hProp,
max([1]) [iDateTarget1],
max([2]) [iDateTarget2],
max([3]) [iDateTarget3],
max([4]) [iDateTarget4]
from (
select
*,
rank() over (partition by hProp order by iWeek) rank#
from [Table X]
) T
pivot (max(iWeek) for rank# in ([1],[2],[3], [4])) pv
group by hProp
) X0
left join [Table X] X1 on X1.hprop = X0.hProp and X1.iWeek = X0.iDateTarget1
left join [Table X] X2 on X2.hprop = X0.hProp and X2.iWeek = X0.iDateTarget2
left join [Table X] X3 on X3.hprop = X0.hProp and X3.iWeek = X0.iDateTarget3
left join [Table X] X4 on X4.hprop = X0.hProp and X4.iWeek = X0.iDateTarget4
这是在不进行多重连接的情况下获得所需结果集的一种方法。它需要更多的设置并使用两个枢轴操作而不是一个,但避免了多个连接。
我承认我必须查一下,但 Ken O'Bonn 有一篇很棒的文章。 https://blogs.msdn.microsoft.com/kenobonn/2009/03/22/pivot-on-two-or-more-fields-in-sql-server/
鉴于:
您可以获得使用手动枢轴描述的结果:
db<>在这里摆弄
我更喜欢使用交叉应用来取消透视,然后使用单个透视。这种技术存在一个问题,因为这两个值最终将被映射到相同的列(类型),因此需要在重新转换为正确类型的过程中进行处理。然而,根据我的经验,这种方法在更大的数据集上表现得非常好。请注意,没有分组依据。
使用相同的源数据:
我使用以下代码对我的解决方案进行了 400 万行的测试,以生成测试数据:
Paul White 解决方案最快,其次是我的。老派赢了!