Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
788 views
in Technique[技术] by (71.8m points)

sql - Is it possible to concatenate column values into a string using CTE?

Say I have the following table:

id|myId|Name
-------------
1 | 3  |Bob 
2 | 3  |Chet
3 | 3  |Dave
4 | 4  |Jim
5 | 4  |Jose
-------------

Is it possible to use a recursive CTE to generate the following output:

3 | Bob, Chet, Date
4 | Jim, Jose

I've played around with it a bit but haven't been able to get it working. Would I do better using a different technique?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I do not recommend this, but I managed to work it out.

Table:

CREATE TABLE [dbo].[names](
    [id] [int] NULL,
    [myId] [int] NULL,
    [name] [char](25) NULL
) ON [PRIMARY]

Data:

INSERT INTO names values (1,3,'Bob')
INSERT INTO names values 2,3,'Chet')
INSERT INTO names values 3,3,'Dave')
INSERT INTO names values 4,4,'Jim')
INSERT INTO names values 5,4,'Jose')
INSERT INTO names values 6,5,'Nick')

Query:

WITH CTE (id, myId, Name, NameCount)
     AS (SELECT id,
                myId,
                Cast(Name AS VARCHAR(225)) Name,
                1                          NameCount
         FROM   (SELECT Row_number() OVER (PARTITION BY myId ORDER BY myId) AS id,
                        myId,
                        Name
                 FROM   names) e
         WHERE  id = 1
         UNION ALL
         SELECT e1.id,
                e1.myId,
                Cast(Rtrim(CTE.Name) + ',' + e1.Name AS VARCHAR(225)) AS Name,
                CTE.NameCount + 1                                     NameCount
         FROM   CTE
                INNER JOIN (SELECT Row_number() OVER (PARTITION BY myId ORDER BY myId) AS id,
                                   myId,
                                   Name
                            FROM   names) e1
                  ON e1.id = CTE.id + 1
                     AND e1.myId = CTE.myId)
SELECT myID,
       Name
FROM   (SELECT myID,
               Name,
               (Row_number() OVER (PARTITION BY myId ORDER BY namecount DESC)) AS id
        FROM   CTE) AS p
WHERE  id = 1 

As requested, here is the XML method:

SELECT myId,
       STUFF((SELECT ',' + rtrim(convert(char(50),Name))
        FROM   namestable b
        WHERE  a.myId = b.myId
        FOR XML PATH('')),1,1,'') Names
FROM   namestable a
GROUP BY myId

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...