Hi @Andrey Piatov
If you want the id value display in one row, then please check this sample:
DECLARE @tbl TABLE (Xml_ID INT IDENTITY PRIMARY KEY, xmldata XML);
INSERT INTO @tbl (xmldata) VALUES
(N'<data><user name="Originator"><value><id>853</id></value></user><user name="Executors"><value><id>503</id></value><value><id>512</id></value><value><id>511</id></value></user></data>'),
(N'<data><user name="Originator"><value><id>853</id></value></user><user name="Executors"><value><id>555</id></value><value><id>544</id></value><value><id>533</id></value><value><id>522</id></value></user></data>'),
(N'<data><user name="Originator"><value><id>853</id></value></user><user name="Executors"><value><id>511</id></value><value><id>566</id></value></user></data>'),
(N'<data><user name="Originator"><value><id>853</id></value></user></data>');
--Use STRING_AGG (Need SQL Server 2017 (14.x) and later)
;WITH CTE AS
(
SELECT Xml_ID,n.x.value('id[1]','INT') AS Executors_Value
FROM @tbl t
OUTER APPLY xmldata.nodes('/data/user[@name="Executors"]/value') n(x) --Use CROSS APPLY instead of OUTER APPLY if you do not want NULL Executors_Value
)
SELECT Xml_ID,STRING_AGG(Executors_Value, ',') WITHIN GROUP (ORDER BY Executors_Value) AS Executors_Value
FROM CTE
GROUP BY Xml_ID
--Try this query if not support STRING_AGG
;WITH CTE AS
(
SELECT Xml_ID,n.x.value('id[1]','INT') AS Executors_Value
FROM @tbl t
OUTER APPLY xmldata.nodes('/data/user[@name="Executors"]/value') n(x)
)
SELECT Xml_ID,
STUFF((SELECT ',' + CAST(Executors_Value AS VARCHAR) FROM CTE WHERE Xml_ID=T.Xml_ID FOR XML PATH('')),1,1,'')AS Executors_Value
FROM CTE T
GROUP BY Xml_ID
Output:
Best regards,
LiHong
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our Documentation to enable e-mail notifications if you want to receive the related email notification for this thread.