使用STUFF或CONCAT命令组合T-SQL中的行

时间:2016-02-10 21:38:55

标签: sql-server database tsql

我正在修改一个程序中的以下查询(这是在我作为软件工程师之前写的,所以请耐心等待......):

SELECT
        Participant.ParticipantID            AS "ParticipantId",
        Stream.StreamName                    AS "StreamName",
        ParticipantStatistics.ConnectTime    AS "ConnectTime",
        ParticipantStatistics.DisconnectTime AS "DisconnectTime",
        FormField.FieldLabel                 AS "FieldLabel",
        RegistrantAnswer.Answer              AS "Answer"
    FROM   ParticipantStatistics
        INNER JOIN Participant ON ParticipantStatistics.ParticipantId = Participant.ParticipantID
        INNER JOIN Registrant ON Registrant.RegistrantId = Participant.RegistrantID
        LEFT OUTER JOIN RegistrantAnswer ON RegistrantAnswer.RegistrantID = Registrant.RegistrantID
        INNER JOIN Event ON Event.EventId = Participant.EventID
        INNER JOIN Stream ON Stream.MediaEventId = Event.EventId
        LEFT OUTER JOIN FormField ON RegistrantAnswer.FormFieldId = FormField.FormFieldId
        LEFT OUTER JOIN (SELECT DISTINCT ParticipantID, SurveyID FROM ParticipantSurvey) 
        AS SurveyCompleted ON SurveyCompleted.ParticipantID = Participant.ParticipantID
    WHERE  Stream.StreamId = '2235'
        AND Participant.Visible = 1
        ORDER  BY Participant.ParticipantID, OrderNumber, ParticipantStatistics.ConnectTime ASC

此查询为我提供了以下信息:

enter image description here

我想要做的是修改上面的查询,将结果作为一行返回如下:

| 315314 | ffbc110729 | 2011-10-27 03:13:06.240 | 2011-10-27 03:17:12.473 | **First Name, Last Name, Email, Company** | **ads, asd, asd@asd.com, asdf** |

组合最后两列的位置,在一行中用逗号分隔。

这可以使用STUFFCONCAT吗?我是T-SQL的新手,所以如果您需要进一步澄清,请告诉我。

最诚挚的问候,

编辑:当我尝试使用STUFF FOR XML PATH进行编辑时,我按以下方式进行了设置:

    SELECT 
        Participant.ParticipantID            AS "ParticipantId",
        Stream.StreamName                    AS "StreamName",
        ParticipantStatistics.ConnectTime    AS "ConnectTime",
        ParticipantStatistics.DisconnectTime AS "DisconnectTime",
    STUFF ((SELECT ','+ FormField.FieldLabel FROM FormField WHERE FormField.FormFieldID = RegistrantAnswer.FormFieldID FOR XML PATH ('')),1,1,'')
    FROM   ParticipantStatistics
        INNER JOIN Participant ON ParticipantStatistics.ParticipantId = Participant.ParticipantID
        INNER JOIN Registrant ON Registrant.RegistrantId = Participant.RegistrantID
        LEFT OUTER JOIN RegistrantAnswer ON RegistrantAnswer.RegistrantID = Registrant.RegistrantID
        INNER JOIN Event ON Event.EventId = Participant.EventID
        INNER JOIN Stream ON Stream.MediaEventId = Event.EventId
        LEFT OUTER JOIN FormField ON RegistrantAnswer.FormFieldId = FormField.FormFieldId
        LEFT OUTER JOIN (SELECT DISTINCT ParticipantID, SurveyID FROM ParticipantSurvey) 
        AS SurveyCompleted ON SurveyCompleted.ParticipantID = Participant.ParticipantID
    WHERE  Stream.StreamId = '2235'
        AND Participant.Visible = 1
        ORDER  BY Participant.ParticipantID, OrderNumber, ParticipantStatistics.ConnectTime ASC

然后我收到以下内容:

enter image description here

同样,我对T-SQL相当新,所以也许我设置错了?非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

尝试这样的事情:

SELECT
    Participant.ParticipantID            AS "ParticipantId",
    Stream.StreamName                    AS "StreamName",
    ParticipantStatistics.ConnectTime    AS "ConnectTime",
    ParticipantStatistics.DisconnectTime AS "DisconnectTime",
    STUFF(
    (SELECT ', ' + FormField.FieldLabel as'text()'
       FROM Registrant
          LEFT OUTER JOIN RegistrantAnswer ON RegistrantAnswer.RegistrantID = Registrant.RegistrantID
          LEFT OUTER JOIN FormField ON RegistrantAnswer.FormFieldId = FormField.FormFieldId
       WHERE Registrant.RegistrantId = Participant.RegistrantID
       FOR XML PATH('')
     ), 1, 2, '') AS "FieldLabel",
    STUFF(
    (SELECT ', ' + RegistrantAnswer.Answer as'text()'
       FROM Registrant
          LEFT OUTER JOIN RegistrantAnswer ON RegistrantAnswer.RegistrantID = Registrant.RegistrantID 
       WHERE Registrant.RegistrantId = Participant.RegistrantID
       FOR XML PATH('')
     ), 1, 2, '') AS "Answer"
FROM   ParticipantStatistics
    INNER JOIN Participant ON ParticipantStatistics.ParticipantId = Participant.ParticipantID
    INNER JOIN Registrant ON Registrant.RegistrantId = Participant.RegistrantID
    INNER JOIN Event ON Event.EventId = Participant.EventID
    INNER JOIN Stream ON Stream.MediaEventId = Event.EventId
WHERE  Stream.StreamId = '2235'
    AND Participant.Visible = 1
ORDER  BY Participant.ParticipantID, OrderNumber, ParticipantStatistics.ConnectTime ASC

答案 1 :(得分:1)

使用STUFF + FOR XML PATH('')通常是SQL Server中连接字符串最实用的。此示例首先在中间临时表中填充结果集,以保持可读性和可管理性。

SELECT *
INTO #fiddle_table
FROM (
        VALUES
            (315314,'ffbc110729',{ts '2011-10-27 03:13:06.240'},{ts '2011-10-27 03:17:12.473'},'First Name','ads'),
            (315314,'ffbc110729',{ts '2011-10-27 03:13:06.240'},{ts '2011-10-27 03:17:12.473'},'Last Name','asd'),
            (315314,'ffbc110729',{ts '2011-10-27 03:13:06.240'},{ts '2011-10-27 03:17:12.473'},'Email','asd@asd.com'),
            (315314,'ffbc110729',{ts '2011-10-27 03:13:06.240'},{ts '2011-10-27 03:17:12.473'},'Company','asdf')
     ) AS v(participantid,streamname,connecttime,disconnecttime,fieldlabel,answer);

;WITH cte AS (
    SELECT DISTINCT
        participantid,streamname,connecttime,disconnecttime
    FROM
        #fiddle_table
)
SELECT
    participantid,streamname,connecttime,disconnecttime,
    fieldlabels=STUFF((
        SELECT ', '+fieldlabel
        FROM #fiddle_table AS i
        WHERE i.participantid=o.participantid
        FOR XML PATH('')
        ),1,2,''
    ),
    answers=STUFF((
        SELECT ', '+answer
        FROM #fiddle_table AS i
        WHERE i.participantid=o.participantid
        FOR XML PATH('')
        ),1,2,''
    )
FROM cte AS o;

DROP TABLE #fiddle_table;

结果:

+---------------+------------+-------------------------+-------------------------+---------------------------------------+-----------------------------+
| participantid | streamname |       connecttime       |     disconnecttime      |              fieldlabels              |           answers           |
+---------------+------------+-------------------------+-------------------------+---------------------------------------+-----------------------------+
|        315314 | ffbc110729 | 2011-10-27 03:13:06.240 | 2011-10-27 03:17:12.473 | First Name, Last Name, Email, Company | ads, asd, asd@asd.com, asdf |
+---------------+------------+-------------------------+-------------------------+---------------------------------------+-----------------------------+