关于sql:我可以用逗号分隔多行到一列吗?

Can I Comma Delimit Multiple Rows Into One Column?

本问题已经有最佳答案,请猛点这里访问。

我正试图在我的SQL Server数据库中合并类似的内容:

1
2
3
4
5
6
[TicketID], [Person]
 T0001       Alice
 T0001       Bob
 T0002       Catherine
 T0002       Doug
 T0003       Elaine

进入这个:

1
2
3
4
[TicketID], [People]
 T0001       Alice, Bob
 T0002       Catherine, Doug
 T0003       Elaine

我需要在SQL Server和Oracle中都这样做。

我已经找到了mysql的GROUP_CONCAT函数,它完全满足了我在这里的需要,但是mysql在这里不是一个选项。

编辑:测试台:

1
2
3
4
5
6
7
8
9
10
11
12
13
DECLARE @Tickets TABLE (
    [TicketID] CHAR(5) NOT NULL,
    [Person] nvarchar(15) NOT NULL
)

INSERT INTO @Tickets VALUES
    ('T0001', 'Alice'),
    ('T0001', 'Bob'),
    ('T0002', 'Catherine'),
    ('T0002', 'Doug'),
    ('T0003', 'Elaine')

SELECT * FROM @Tickets

以下是在SQL Server 2005+中工作的解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT t.TicketID,
       STUFF(ISNULL((SELECT ', ' + x.Person
                FROM @Tickets x
               WHERE x.TicketID = t.TicketID
            GROUP BY x.Person
             FOR XML PATH (''), TYPE).value('.','VARCHAR(max)'), ''), 1, 2, '') [No Preceeding Comma],
       ISNULL((SELECT ', ' + x.Person
                FROM @Tickets x
               WHERE x.TicketID = t.TicketID
            GROUP BY x.Person
             FOR XML PATH (''), TYPE).value('.','VARCHAR(max)'), '') [Preceeding Comma IF NOT Empty]
  FROM @Tickets t
GROUP BY t.TicketID

参考文献:

  • 资料(Transact-SQL)


以及mysql版本,为了完整性:

1
2
3
4
5
6
7
SELECT
    TicketId,
    GROUP_CONCAT(Person ORDER BY Person SEPARATOR ', ') People
FROM
    TABLE
GROUP BY
    TicketId


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
DECLARE @Tickets TABLE (
    [TicketID] CHAR(5) NOT NULL,
    [Person] nvarchar(15) NOT NULL
)
INSERT INTO @Tickets VALUES
    ('T0001', 'Alice'),
    ('T0001', 'Bob'),
    ('T0002', 'Catherine'),
    ('T0002', 'Doug'),
    ('T0003', 'Elaine')

SELECT * FROM @Tickets

SELECT [TicketID],
STUFF((SELECT ',' + Person FROM @Tickets WHERE (
TicketID=RESULT.TicketID) FOR XML PATH ('')),1,1,'') AS BATCHNOLIST
FROM @Tickets AS RESULT
GROUP BY TicketID


我在Oracle中找到了一种实现这一点的方法,但我仍然需要在SQL Server中实现这一点。

来自http://technology.amis.nl/blog/6118/oracle-rdbms-11gr2-listagg-new-aggregation-operator-for-creating-comma-delimited-strings(感谢Tanging)(Oracle 11及更高版本)

1
2
3
4
5
6
7
SELECT
    TicketId,
    listagg(Person, ', ') People
FROM
    TABLE
GROUP BY
    TicketId

发件人:http://halisway.blogspot.com/2006/08/oracle-groupconcat-updated-again.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
WITH
    DATA
AS
  (
    SELECT
        TicketId,
        Person,
        ROW_NUMBER() OVER (partition BY TicketId ORDER BY Person)"rownum",
        COUNT(*) OVER (partition BY TicketId)"count"
    FROM
        TABLE
  )
SELECT
    TicketId,
    LTRIM(sys_connect_by_path(Person,','),',') People
FROM
    DATA
WHERE
   "rownum" ="count"
START WITH
   "rownum" = 1
CONNECT BY
    prior TicketId = TicketId
  AND
    prior"rownum" ="rownum" - 1
ORDER BY
    TicketId


一个例子

1
2
3
4
5
6
7
8
SELECT DISTINCT
    t.TicketID,
    STUFF((SELECT ', ', i.Person AS [text()]
           FROM @Tickets i
           WHERE i.TicketID = t.TicketID
           FOR XML PATH ('')), 1, 2, '') AS People
FROM
    @Tickets t

……或者试试…………

1
2
3
4
5
6
7
8
SELECT DISTINCT
    t.TicketID,
    STUFF((SELECT ', ' + i.Person    /* notice this line is different */
           FROM @Tickets i
           WHERE i.TicketID = t.TicketID
           FOR XML PATH ('')), 1, 2, '') AS People
FROM
    @Tickets t

/*当我用这个做我的桌子时,这个很有效,信用卡就会被我的经理抢走!*/