SQL Server 2012:依据序列号将3列数据拆分生成多列
解决SQL Server 2012中行转列(拆分10号之后的行到新列)的方案
嘿,这个行转列的需求我在SQL Server里处理过好多次了,刚好适配你30行数据拆成每10行一组的场景,给你两种方案,看你实际情况选:
情况1:原表的序列号是连续的
如果你的SerialNo列是从1到30连续递增的,那可以直接用序列号来分组:
WITH GroupedData AS ( SELECT -- 标记每组内的行位置(1-10) ROW_IN_GROUP = (SerialNo - 1) % 10 + 1, Column1, Column2, -- 把30行分成3组(1-10为组1,11-20为组2,21-30为组3) GROUP_NUMBER = ((SerialNo - 1) / 10) + 1 FROM OriginalTable ) SELECT ROW_IN_GROUP AS 原组内行号, -- 第一组(1-10行)的列 MAX(CASE WHEN GROUP_NUMBER = 1 THEN Column1 END) AS Column1_1_10, MAX(CASE WHEN GROUP_NUMBER = 1 THEN Column2 END) AS Column2_1_10, -- 第二组(11-20行)的列 MAX(CASE WHEN GROUP_NUMBER = 2 THEN Column1 END) AS Column1_11_20, MAX(CASE WHEN GROUP_NUMBER = 2 THEN Column2 END) AS Column2_11_20, -- 第三组(21-30行)的列 MAX(CASE WHEN GROUP_NUMBER = 3 THEN Column1 END) AS Column1_21_30, MAX(CASE WHEN GROUP_NUMBER = 3 THEN Column2 END) AS Column2_21_30 FROM GroupedData GROUP BY ROW_IN_GROUP ORDER BY ROW_IN_GROUP;
情况2:原表的序列号不连续
如果你的SerialNo可能有缺失或者不按顺序,那先给所有行生成连续的行号,再分组:
WITH NumberedData AS ( SELECT SerialNo, Column1, Column2, -- 生成连续的行号,确保按原顺序分组 RN = ROW_NUMBER() OVER (ORDER BY SerialNo) FROM OriginalTable ), GroupedData AS ( SELECT ROW_IN_GROUP = (RN - 1) % 10 + 1, Column1, Column2, GROUP_NUMBER = ((RN - 1) / 10) + 1 FROM NumberedData ) SELECT ROW_IN_GROUP AS 原位置行号, MAX(CASE WHEN GROUP_NUMBER = 1 THEN Column1 END) AS Column1_前10行, MAX(CASE WHEN GROUP_NUMBER = 1 THEN Column2 END) AS Column2_前10行, MAX(CASE WHEN GROUP_NUMBER = 2 THEN Column1 END) AS Column1_11至20行, MAX(CASE WHEN GROUP_NUMBER = 2 THEN Column2 END) AS Column2_11至20行, MAX(CASE WHEN GROUP_NUMBER = 3 THEN Column1 END) AS Column1_21至30行, MAX(CASE WHEN GROUP_NUMBER = 3 THEN Column2 END) AS Column2_21至30行 FROM GroupedData GROUP BY ROW_IN_GROUP ORDER BY ROW_IN_GROUP;
关键逻辑说明
- 用CTE先给每行分配组内位置和组号,把30行拆成3个10行的组;
- 用
CASE配合MAX函数把纵向的组数据转成横向的列(因为每个组内的每个位置只有一个值,MAX不会影响结果); - 如果你需要调整分组数量或者列名,只需要修改
GROUP_NUMBER的判断和列别名就行。
内容的提问来源于stack exchange,提问作者Bahr
相关产品推荐
相关产品推荐

