如何调整SQL查询将Saving列转为新行并按指定顺序输出结果?
解决SQL行转列并保持指定顺序的问题
原始数据表
emp checking saving a 100 500 a 200 1000 c 300 2000 d 300 200 d 100 50
期望输出结果
emp checking a 100 a 500 a 200 a 1000 c 300 c 2000 d 300 d 200 d 100 d 50
现有问题
之前尝试的两种查询都无法满足输出顺序要求:
- Cross Apply查询返回了
checking和saving两列,不符合期望的单列结构; - Union All查询仅按
emp排序,无法保证同一条原始记录的checking在前、saving在后,也无法保留同emp下原始记录的先后顺序。
修正后的查询方案
方案1:带行号的Cross Apply实现
先给每个emp下的原始记录分配行号,确保原始顺序,再通过Cross Apply拆分字段,最后按行号和拆分顺序排序:
SELECT t.emp, CASE v.n WHEN 1 THEN t.checking ELSE t.saving END AS checking FROM ( -- 给每个emp分组内的记录分配行号,保留原始顺序 SELECT *, ROW_NUMBER() OVER (PARTITION BY emp ORDER BY (SELECT NULL)) AS row_num FROM Table1 ) t -- 为每条原始记录生成两行,分别对应checking和saving CROSS APPLY (VALUES (1), (2)) v(n) -- 按emp、原始行号、拆分顺序排序 ORDER BY t.emp, t.row_num, v.n;
方案2:带排序标识的Union All实现
通过给两个子查询添加排序键,确保同一条记录的checking先于saving,同时保留原始记录的顺序:
SELECT emp, val AS checking FROM ( -- 给checking分配偶数排序键 SELECT emp, checking AS val, ROW_NUMBER() OVER (PARTITION BY emp ORDER BY (SELECT NULL)) * 2 AS sort_key FROM Table1 UNION ALL -- 给saving分配奇数排序键,确保在同一条原始记录的checking之后 SELECT emp, saving AS val, ROW_NUMBER() OVER (PARTITION BY emp ORDER BY (SELECT NULL)) * 2 + 1 AS sort_key FROM Table1 ) t ORDER BY emp, sort_key;
内容的提问来源于stack exchange,提问作者Tsang
相关产品推荐
相关产品推荐

