我在 SQL Server 2008 中有一个疑问如何用逗号分隔(,)连接具有列顺序的多个列
时间安排
Id | Name | days |daysfrequency|scheduletime
1 | a |Day4 |Monthly |22:10
1 | a |Thu |Weekly |07:30
1 | a |Fri |Daily |23:10
2 | b |Mon |Weekly |20:00
2 | b |Tue |Weekly |23:10
2 | b |Wed |Weekly |18:10
2 | b |Thu |Weekly |10:23
2 | b |Fri |Weekly |1:23
根据上述数据,我想要如下输出。
id | Name | Days |DaysFrequency | ScheduleTIme
1 |a |Days4,THu,Fri |Monthly,Weekly,Daily |22:10,07:30,23:10
2 |b |Mon,Tue,Wed,Thu,Fri|Weekly |20:00,23:10,18:10,10:23,1:23
我已经尝试过如下。
select id ,name
,Days=stuff((select distinct ',' days from timeschedule t
where t.id=t1.id and t.name=t1.name
for xml path('')),1,1,'')
,daysfrequency=stuff((select distinct ',' daysfrequency from timeschedule t
where t.id=t1.id and t.name=t1.name
for xml path('')),1,1,'')
,scheduletime=stuff((select distinct ',' scheduletime from timeschedule t
where t.id=t1.id and t.name=t1.name
for xml path('')),1,1,'')
from timeschedule t1 group by id,name
使用上面的查询,它没有给出days、daysfrequenc、scheduletime中的预期顺序。
有人可以告诉我如何在 SQL Server 2008 版本中编写查询来完成此任务吗?
请尝试以下解决方案。
正如@Squirrel 正确提到的:
您需要表中的另一列来确定所需的 订购
SQL#1
-- DDL and sample data population, start
DECLARE @tbl TABLE (id INT, _name CHAR(1), days VARCHAR(10), daysfrequency VARCHAR(10), scheduletime VARCHAR(10));
INSERT INTO @tbl (id,_name,days,daysfrequency,scheduletime) VALUES
(1, 'a', 'Day4','Monthly','22:10'),
(1, 'a', 'Thu', 'Weekly', '07:30'),
(1, 'a', 'Fri', 'Daily', '23:10'),
(2, 'b', 'Mon', 'Weekly', '20:00'),
(2, 'b', 'Tue', 'Weekly', '23:10'),
(2, 'b', 'Wed', 'Weekly', '18:10'),
(2, 'b', 'Thu', 'Weekly', '10:23'),
(2, 'b', 'Fri', 'Weekly', '1:23');
-- DDL and sample data population, end
-- Method #1
SELECT id, _name
, Days=STUFF((SELECT DISTINCT ',' + days
FROM @tbl t
WHERE t.id=t1.id and t._name=t1._name
FOR xml path('')),1,1,'')
, daysfrequency=STUFF((SELECT DISTINCT ',' + daysfrequency
FROM @tbl AS t
WHERE t.id=t1.id and t._name=t1._name
FOR XML PATH('')),1,1,'')
, scheduletime=STUFF((SELECT DISTINCT ',' + scheduletime
FROM @tbl AS t
WHERE t.id=t1.id and t._name=t1._name
FOR XML PATH('')),1,1,'')
FROM @tbl AS t1
GROUP BY id,_name;
输出
id | _名字 | 天 | 天频 | 安排时间 |
---|---|---|---|---|
1 | a | 第四天,周五,周四 | 每日、每月、每周 | 07:30,22:10,23:10 |
2 | b | 周五、周一、周四、周二、周三 | 每周 | 1:23,10:23,18:10,20:00,23:10 |
SQL#2
-- Method #2
-- pure XQuery
DECLARE @separator CHAR(1) = ',';
SELECT id, _name
, (SELECT days FROM @tbl AS t
WHERE t.id=t1.id AND t._name=t1._name
FOR XML PATH(''), TYPE, ROOT('root')).query('
for $i in /root/days
return if ($i is (/root/days[last()])[1]) then string($i)
else concat($i, sql:variable("@separator"))
').value('.', 'NVARCHAR(MAX)') AS Days
, (SELECT DISTINCT daysfrequency FROM @tbl AS t
WHERE t.id=t1.id AND t._name=t1._name
FOR XML PATH(''), TYPE, ROOT('root')).query('
for $i in /root/daysfrequency
return if ($i is (/root/daysfrequency[last()])[1]) then string($i)
else concat($i, sql:variable("@separator"))
').value('.', 'NVARCHAR(MAX)') AS daysfrequency
, (SELECT DISTINCT scheduletime FROM @tbl AS t
WHERE t.id=t1.id AND t._name=t1._name
FOR XML PATH(''), TYPE, ROOT('root')).query('
for $i in /root/scheduletime
return if ($i is (/root/scheduletime[last()])[1]) then string($i)
else concat($i, sql:variable("@separator"))
').value('.', 'NVARCHAR(MAX)') AS scheduletime
FROM @tbl AS t1
GROUP BY id,_name;
输出
id | _名字 | 天 | 天频 | 安排时间 |
---|---|---|---|---|
1 | a | 第四天,周四,周五 | 每日、每月、每周 | 07:30、22:10、23:10 |
2 | b | 周一、周二、周三、周四、周五 | 每周 | 1:23、10:23、18:10、20:00、23:10 |