我有一个数据库表,其中包含在多个办公地点工作的用户。这些位置由一个数字标识,在我的表格中,我有几个用户出现在他们工作的每个办公地点的几行上。我想要的是一个SQL查询,它将结合记录并显示一个以昏迷分隔的字段中的所有办公室位置。
这是我的原始表:
Id UserName OfficeNumber
--- --------- -------------
1 user01 200
2 user02 220
3 user01 290
4 user03 089
5 user02 019
运行查询后,我希望我的最终表格如下所示:
Id UserName OfficeNumber
--- --------- -------------
1 user01 200, 290
2 user02 220, 019
3 user03 089
任何帮助都将受到高度赞赏。
答案 0 :(得分:2)
您可以使用SQL-Servers XML扩展将行连接到列:
SELECT ID,
UserName,
OfficeNumber = STUFF(( SELECT ',' + CAST(OfficeNumber AS VARCHAR(3))
FROM YourTable b
WHERE a.UserName = b.UserName
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM ( SELECT ID = MIN(ID), UserName
FROM YourTable
GROUP BY UserName
) a;
<强> Example on SQL Fiddle 强>
有another question on SO有人问过这种方法的复杂程度,并且有一些答案,所以我不再重复这里的解释了。
修改强>
看起来您没有为每个用户名取最低ID,但重新分配新号码作为ID,如果要根据每个用户名的最低原始ID重新分配ID,则可以使用:
SELECT ID,
UserName,
OfficeNumber = STUFF(( SELECT ',' + CAST(OfficeNumber AS VARCHAR(3))
FROM YourTable b
WHERE a.UserName = b.UserName
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM ( SELECT ID = ROW_NUMBER() OVER(ORDER BY MIN(ID)), UserName
FROM YourTable
GROUP BY UserName
) a;
<强> Example on SQL-Fiddle 强>
或者如果按字母顺序排列,您可以使用
SELECT ID = ROW_NUMBER() OVER(ORDER BY a.UserName),
UserName,
OfficeNumber = STUFF(( SELECT ',' + CAST(OfficeNumber AS VARCHAR(3))
FROM YourTable b
WHERE a.UserName = b.UserName
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM YourTable a
GROUP BY a.UserName
<强> Example on SQL-Fiddle 强>
答案 1 :(得分:1)
查询:
<强> SQLFIDDLEExample 强>
SELECT ROW_NUMBER()OVER(ORDER BY c1.UserName) AS Id,
c1.UserName,
STUFF((SELECT ', ' +x.OfficeNumber
FROM Table1 x
WHERE c1.UserName = x.UserName
FOR XML PATH ('')
),1,1,'') as OfficeNumber
FROM Table1 c1
GROUP BY c1.UserName
结果:
| ID | USERNAME | OFFICENUMBER |
|----|----------|--------------|
| 1 | user01 | 200, 290 |
| 2 | user02 | 220, 019 |
| 3 | user03 | 089 |