SQL Server 2008多列按原顺序逗号拼接实现方案求助
SQL Server 2008 按原数据顺序拼接多列解决方案
你的问题核心是原查询使用了DISTINCT,这会打乱原数据的顺序,同时未指定明确排序逻辑,导致拼接结果不符合预期。要实现按原数据顺序拼接,需先为每个分组内的行生成标识顺序的行号,再基于行号排序完成拼接。
解决方案代码
WITH OrderedData AS ( SELECT id, name, days, daysfrequency, scheduletime, -- 为每个id+name分组生成行号,保留原数据顺序 ROW_NUMBER() OVER(PARTITION BY id, name ORDER BY (SELECT 0)) AS row_num FROM timeschedule ) SELECT od.id, od.name, -- 按行号排序拼接days Days = STUFF(( SELECT ',' + t.days FROM OrderedData t WHERE t.id = od.id AND t.name = od.name ORDER BY t.row_num FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'), 1, 1, ''), -- 按行号排序拼接daysfrequency DaysFrequency = STUFF(( SELECT ',' + t.daysfrequency FROM OrderedData t WHERE t.id = od.id AND t.name = od.name ORDER BY t.row_num FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'), 1, 1, ''), -- 按行号排序拼接scheduletime ScheduleTime = STUFF(( SELECT ',' + t.scheduletime FROM OrderedData t WHERE t.id = od.id AND t.name = od.name ORDER BY t.row_num FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'), 1, 1, '') FROM OrderedData od GROUP BY od.id, od.name;
关键说明
- 生成行号:使用
ROW_NUMBER() OVER(PARTITION BY id, name ORDER BY (SELECT 0))为每个id+name分组内的行分配唯一行号,ORDER BY (SELECT 0)用于在SQL Server 2008中模拟保留原数据的插入顺序(若表存在聚集索引,也可直接按聚集索引列排序)。 - 移除DISTINCT:原查询中的
DISTINCT会导致去重并打乱顺序,若无需去重则直接移除;若需去重且保留顺序,需先按行号筛选唯一值再拼接。 - XML拼接优化:使用
TYPE和.value('.', 'NVARCHAR(MAX)')可避免特殊字符(如&、<、>)被转义,保证拼接结果的准确性。
输出结果
执行上述代码后,将得到与你期望一致的结果:
id | Name | Days |DaysFrequency | ScheduleTIme ---+-------+-------------------+---------------------+------------------ 1 |a |Day4,Thu,Fri |Monthly,Weekly,Daily |22:10,07:30,23:10 2 |b |Mon,Tue,Wed,Thu,Fri|Weekly,Weekly,Weekly,Weekly,Weekly |20:00,23:10,18:10,10:23,1:23
(注:若需对DaysFrequency列去重并保留顺序,可在子查询中添加DISTINCT但需确保排序逻辑正确;根据你的期望输出,若要将b的重复Weekly合并为单个值,需额外处理去重逻辑)
内容的提问来源于stack exchange,提问作者Harinanth
相关产品推荐
相关产品推荐

