0

I am on version 2012 and need to use FOR XML PATH to get a comma separated string for like projects. I have a temp table that I have compiled and would like to combine people based on project numbers. The results combine all people into one list for all projects. I am looking to get specific to project.

select #Team.WBS1, 
    stuff((
        Select ',', #Team.Team as [text()]
        from #Team
        Where #team.WBS1 = #team.wbs1
        for xml path('')
    ), 1, 1, '') 
from #Team

I am getting the same results for every project number.

Project People
1 john, jim, sean, billy
1 john, jim, sean, billy
1 john, jim, sean, billy
1 john, jim, sean, billy
2 john, jim, sean, billy
3 john, jim, sean, billy
3 john, jim, sean, billy
4 john, jim, sean, billy
4 john, jim, sean, billy

I need results like this

Project People
1 john, jim, sean, billy
2 billy
3 jim, sean,
4 john, jim, billy

Data looks like this

Project People
1 john
1 jim
1 sean
1 billy
2 billy
3 jim
3 sean
4 john
4 jim, billy
7
  • 2
    You need to use a different alias for your table in your sub-query. Commented Jul 1, 2024 at 19:59
  • its all coming from one table, not sure what you mean Commented Jul 1, 2024 at 20:05
  • 1
    Yes, but you are trying to correlate your sub-query with your outer query, and because it's the same table you need to differentiate it. This #team.WBS1 = #team.wbs1 is like saying 1=1 because it's not differentiating inner and outer Commented Jul 1, 2024 at 20:06
  • I assume the last row of your "data looks like this" should actually be 2 rows Commented Jul 1, 2024 at 20:10
  • Does this answer your question: String_agg for SQL Server before 2017 (Specifically I cover how you do this in my answer.) Commented Jul 1, 2024 at 20:13

2 Answers 2

1

You need to do some grouping first:

WITH data AS (
    SELECT  *
    FROM    (
    VALUES  (1, N'john')
    ,   (1, N'jim')
    ,   (1, N'sean')
    ,   (1, N'billy')
    ,   (2, N'billy')
    ,   (3, N'jim')
    ,   (3, N'sean')
    ,   (4, N'john')
    ,   (4, N'jim, billy')
) t (Project,People)
)
SELECT  Project
,   STUFF((
    SELECT  ',' + People
    FROM    data dInner
    WHERE   dInner.Project = d.Project
    FOR xml path(''), type
    ).value('text()[1]', 'NVARCHAR(MAX)'), 1, 1, '') AS People
FROM    data d
GROUP BY project

And "join" the subquery table with the main one.

Actually, my advice would be to always use aliases for tables, this avoids a lot of errors with incorrect JOINs.

Output:

Project People
1 john,jim,sean,billy
2 billy
3 jim,sean
4 john,jim, billy

A little side-note is that it's good to use an ORDER BY when doing the FOR XML thing, so the values are always sorted the same way

Sign up to request clarification or add additional context in comments.

2 Comments

I gave a snapshot of the data, there are 312 projects (will get bigger as time goes on) with over 20+ (will grow as new projects get added). Grouping all of them doesnt seem feasable. I would love to use String_Agg but 2012 doesnt suport it.
I just mean you need to add GROUP BY to the outer part, so you don't get duplicates :)
0

Alias the tables with different aliases:

   select distinct t1.WBS1, 
        stuff((
            Select ',', t2.Team as [text()]
            from #Team t2
            Where t2.WBS1 = t1.wbs1
            for xml path('')
        ), 1, 1, '') 
    from #Team t1;

DBFiddle demo

1 Comment

There should be a way to force downvoters to make an explanation, especially if it is taking them for months to think about it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.