How to use GROUP BY to concatenate strings in SQL Server?

前端 未结 20 2350
无人及你
无人及你 2020-11-21 04:33

How do I get:

id       Name       Value
1          A          4
1          B          8
2          C          9

to

id               


        
相关标签:
20条回答
  • 2020-11-21 04:42

    This kind of question is asked here very often, and the solution is going to depend a lot on the underlying requirements:

    https://stackoverflow.com/search?q=sql+pivot

    and

    https://stackoverflow.com/search?q=sql+concatenate

    Typically, there is no SQL-only way to do this without either dynamic sql, a user-defined function, or a cursor.

    0 讨论(0)
  • 2020-11-21 04:43

    using XML path will not perfectly concatenate as you might expect... it will replace "&" with "&amp;" and will also mess with <" and "> ...maybe a few other things, not sure...but you can try this

    I came across a workaround for this... you need to replace:

    FOR XML PATH('')
    )
    

    with:

    FOR XML PATH(''),TYPE
    ).value('(./text())[1]','VARCHAR(MAX)')
    

    ...or NVARCHAR(MAX) if thats what youre using.

    why the hell doesn't SQL have a concatenate aggregate function? this is a PITA.

    0 讨论(0)
  • 2020-11-21 04:43

    didn't see any cross apply answers, also no need for xml extraction. Here is a slightly different version of what Kevin Fairchild wrote. It's faster and easier to use in more complex queries:

       select T.ID
    ,MAX(X.cl) NameValues
     from #YourTable T
     CROSS APPLY 
     (select STUFF((
        SELECT ', ' + [Name] + ':' + CAST([Value] AS VARCHAR(MAX))
        FROM #YourTable 
        WHERE (ID = T.ID) 
        FOR XML PATH(''))
      ,1,2,'')  [cl]) X
      GROUP BY T.ID
    
    0 讨论(0)
  • 2020-11-21 04:46

    Another example without the garbage: ",TYPE).value('(./text())[1]','VARCHAR(MAX)')"

    WITH t AS (
        SELECT 1 n, 1 g, 1 v
        UNION ALL 
        SELECT 2 n, 1 g, 2 v
        UNION ALL 
        SELECT 3 n, 2 g, 3 v
    )
    SELECT g
            , STUFF (
                    (
                        SELECT ', ' + CAST(v AS VARCHAR(MAX))
                        FROM t sub_t
                        WHERE sub_t.g = main_t.g
                        FOR XML PATH('')
                    )
                    , 1, 2, ''
            ) cg
    FROM t main_t
    GROUP BY g
    

    Input-output is

    *************************   ->  *********************
    *   n   *   g   *   v   *       *   g   *   cg      *
    *   -   *   -   *   -   *       *   -   *   -       *
    *   1   *   1   *   1   *       *   1   *   1, 2    *
    *   2   *   1   *   2   *       *   2   *   3       *
    *   3   *   2   *   3   *       *********************
    *************************   
    
    0 讨论(0)
  • 2020-11-21 04:49

    Just to add to what Cade said, this is usually a front-end display thing and should therefore be handled there. I know that sometimes it's easier to write something 100% in SQL for things like file export or other "SQL only" solutions, but most of the times this concatenation should be handled in your display layer.

    0 讨论(0)
  • 2020-11-21 04:50

    Let's get very simple:

    SELECT stuff(
        (
        select ', ' + x from (SELECT 'xxx' x union select 'yyyy') tb 
        FOR XML PATH('')
        )
    , 1, 2, '')
    

    Replace this line:

    select ', ' + x from (SELECT 'xxx' x union select 'yyyy') tb
    

    With your query.

    0 讨论(0)
提交回复
热议问题