如何使用STUFF和FOR XML PATH分隔与行对应的唯一值

问题描述

我正在运行此查询

SELECT A.PeripheralNumber,P.LoginName,P.FirstName,P.LastName,A.EnterpriseName,A.AgentDeskSettingsID,AttributeValues = 
STUFF((SELECT ',' + ATT.EnterpriseName+'='+AT.AttributeValue AS Attribute
FROM Agent_Attribute AT
LEFT JOIN Agent A ON A.SkillTargetID = AT.SkillTargetID
LEFT JOIN Attribute ATT ON ATT.AttributeID = AT.AttributeID
WHERE A.SkillTargetID IN ('26379','24111')
ORDER BY Attribute
FOR XML PATH (''),TYPE ).value('.','VARCHAR(MAX)'),1,'')
FROM Agent A
LEFT JOIN Person P ON P.PersonID = A.PersonID
LEFT JOIN Agent_Desk_Settings ADS ON ADS.AgentDeskSettingsID = A.AgentDeskSettingsID
WHERE A.SkillTargetID IN ('26379','24111')
AND A.EnterpriseName LIKE 'PG_8%'
AND P.FirstName NOT LIKE '%Test%'
GROUP BY A.PeripheralNumber,A.AgentDeskSettingsID

我得到的结果如下:

|PeripheralNumber|LoginName|FirstName|LastName|EnterpriseName|AgentDeskSettingsID|AttributeValues                                                                                                 |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|551628          |551628   |John     |Doe     |Doe_John      |5104               |AAH_CSC_EXIST=5,AAH_CSC_FNOL=5,AAH_CSC_ROTL=5,AAH_SERVICE_AUTO=10,AAH_SERVICE_REBRAND=5,AAH_SERVICE_WEB_ONLINE=10|
|558792          |558792   |Jane     |Doe     |Doe_Jane      |5103               |AAH_CSC_EXIST=5,AAH_SERVICE_WEB_ONLINE=10|
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

正在发生的事情是John Doe和Jane Doe的唯一AttributeValues正在组合。我需要的结果如下:

|PeripheralNumber|LoginName|FirstName|LastName|EnterpriseName|AgentDeskSettingsID|AttributeValues                                                                                                 |
------------------------------------------------------------------------------------------------------------------------------------------------------
|551628          |551628   |John     |Doe     |Doe_John      |5104               |AAH_SERVICE_AUTO=10,AAH_CSC_ROTL=5                      |
------------------------------------------------------------------------------------------------------------------------------------------------------

帮助!这是MS sql Server 2016

解决方法

cross applyouter apply。像这样:

SELECT DISTINCT A.PeripheralNumber,P.LoginName,P.FirstName,P.LastName,A.EnterpriseName,A.AgentDeskSettingsID,DS.AttributeValues
FROM Agent A
LEFT JOIN Person P
    ON A.PersonID = P.PersonID
LEFT JOIN Agent_Desk_Settings ADS
    ON A.AgentDeskSettingsID = ADS.AgentDeskSettingsID
OUTER APPLY
(
    SELECT STUFF((SELECT ',' + ATT.EnterpriseName+'='+AT.AttributeValue AS Attribute
    FROM Agent_Attribute AT
    INNER JOIN Attribute ATT
        ON ATT.AttributeID = AT.AttributeID
    WHERE A.SkillTargetID = AT.SkillTargetID
    ORDER BY Attribute
    FOR XML PATH (''),TYPE ).value('.','VARCHAR(MAX)'),1,'')
) DS (AttributeValues)
WHERE A.SkillTargetID IN ('26379','24111')
    AND A.EnterpriseName LIKE 'PG_8%'
    AND P.FirstName NOT LIKE '%Test%'
,

如果您想将值限制为一个人,则需要与该人建立关联:

STUFF((SELECT ',' + ATT.EnterpriseName+'='+AT.AttributeValue AS Attribute
       FROM Agent_Attribute AT JOIN
            Agent A 
            ON A.SkillTargetID = AT.SkillTargetID
            Attribute ATT
            ON ATT.AttributeID = AT.AttributeID
            WHERE A.SkillTargetID IN (26379,24111) AND
                  AA.PersonID = p.PersonId
            ORDER BY Attribute
            FOR XML PATH (''),TYPE
           ).value('.','')

请注意,我从看起来像数字常量的地方删除了单引号。如果这些确实是字符串,请加上单引号。

此外,LEFT JOIN在相关子查询中是多余的。