How to “Implode” (de-normalize/concat) multiple columns into a single column?

后端 未结 4 1940
别跟我提以往
别跟我提以往 2021-01-17 23:46

I have a query which outputs something like this:

+-------+----+--------------+
| F_KEY | EV | OTHER_COLUMN |
+-------+----+--------------+
| 100   | 1  | ..         


        
相关标签:
4条回答
  • 2021-01-18 00:03

    Look into using FOR XML PATH, you can convert it use the xml string just like a varchar, this supports a seperating character/expression as well. It will go at the end of your query but will most likely require you to use a subquery structure.

    0 讨论(0)
  • 2021-01-18 00:06

    You can probably use the technique described here. (Full disclosure: that's my blog.) It talks about generating concatenated strings in T-SQL, without use of cursors.

    0 讨论(0)
  • 2021-01-18 00:15

    here is the best concatenation method, it will not expand special characters like other XML methods:

    --Concatenation with FOR XML & eliminating control/encoded char expansion "& < >"
    set nocount on;
    declare @YourTable table (RowID int, HeaderValue int, ChildValue varchar(5))
    insert into @YourTable VALUES (1,1,'CCC')
    insert into @YourTable VALUES (2,2,'B<&>B')
    insert into @YourTable VALUES (3,2,'AAA')
    insert into @YourTable VALUES (4,3,'<br>')
    insert into @YourTable VALUES (5,3,'A & Z')
    set nocount off
    SELECT
        t1.HeaderValue
            ,STUFF(
                       (SELECT
                            ', ' + t2.ChildValue
                            FROM @YourTable t2
                            WHERE t1.HeaderValue=t2.HeaderValue
                            ORDER BY t2.ChildValue
                            FOR XML PATH(''), TYPE
                       ).value('.','varchar(max)')
                       ,1,2, ''
                  ) AS ChildValues
        FROM @YourTable t1
        GROUP BY t1.HeaderValue
    

    OUTPUT:

    HeaderValue ChildValues
    ----------- ---------------
    1           CCC
    2           AAA, B<&>B
    3           <br>, A & Z
    
    (3 row(s) affected)
    
    0 讨论(0)
  • 2021-01-18 00:23

    You can do it easily enough with a function: Assumes you are going to be searching the same column/table all the time. Dynamic SQL needed if you want to be able to vary the columns/tables

    CREATE FUNCTION [dbo].[fn_recursion]
    (@F_KEY int)  
    RETURNS varchar(2000) AS 
    BEGIN 
    
        DECLARE @ReturnVal Varchar(2000)
    
        SELECT @ReturnVal = COALESCE(@ReturnVal + ', ', '') + EV
        FROM TABLE2 
        WHERE @F_KEY = @F_KEY
    
        RETURN ISNULL(@ReturnVal,'')
    
    END
    GO
    
    
    SELECT
        F_KEY,
        EV = [dbo].[fn_recursion](F_KEY),
        OTHER_COLUMN
    FROM
        TABLE1
    JOIN
        TABLE2 ON F_KEY = TABLE2.ID
    WHERE
        EVENT_TIME BETWEEN '2011-01-01 00:00:00.000' AND '2011-12-31 23:59:59.999'
    ORDER BY
        EVENT_TIME ASC
    
    GO
    
    DROP FUNCTION [dbo].[fn_recursion]
    GO
    
    0 讨论(0)
提交回复
热议问题