SQL - 将多行与相似的用户名组合在一起

时间:2013-10-04 12:36:19

标签: sql sql-server

我有一个数据库表,其中包含在多个办公地点工作的用户。这些位置由一个数字标识,在我的表格中,我有几个用户出现在他们工作的每个办公地点的几行上。我想要的是一个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

任何帮助都将受到高度赞赏。

2 个答案:

答案 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 |