Archive for the 'T-SQL' Category

T-SQL: Collapse multiple rows of SQL data into a single string

This posting may not be useful to anyone but me again in the future, but I needed to figure out how to take some text and other information from multiple rows of a table and combine them into a single string for display.

My main goal was to build a string which is a summary of a number of activities that were logged against a specific entity.  First I gathered the important activity details into a table variable defined as:

    declare @Activities table
    (
        ActivityID            uniqueidentifier,
        RegardingObjectID    uniqueidentifier,
        ActivityTypeName    nvarchar(50),
        ActivityDate        datetime,
        DescriptionText        nvarchar(max),
        CreatorId            uniqueidentifier,
        CreatorName            nvarchar(200) 
    )

Once that was populated (I’ll omit that part, as it’s pretty specific to our source system schema and not interesting for the example), I then took each of the activity entries and flattened them down into one string each in another table variable @ActivitiesStrings:

    -- Now, roll up each activity into a string representation (one per activity)
    declare @ActivitiesStrings table ( ActivityString nvarchar(max) )

    insert into @ActivitiesStrings (ActivityString)
    select '--------------------------' + char(13) + char(10) + '** ' + ActivityTypeName + 
        case when ActivityTypeName <> 'Opportunity Close' then ' added by ' else 'd by ' end +
        CreatorName + ' on ' + 
        datename(m, ActivityDate) + ' ' + datename(d, ActivityDate) + ', ' + datename(yyyy, ActivityDate) + ', ' +
        case when datepart(hh, ActivityDate) < 12 then  datename(hh, ActivityDate) else convert(nvarchar(2),datepart(hh, ActivityDate) - 12) end +
        ':' + right('00' + datename(n, ActivityDate), 2) +
        case when datepart(hh, ActivityDate) < 12 then ' AM' else ' PM' end + char(13) + char(10) + 
        'Description:' + char(13) + char(10) + 
        case when isnull(DescriptionText,'') = '' 
            then 'N/A'
            else replace(DescriptionText,  char(10), char(13) + char(10))
        end as ActivityString
    from @Activities
    order by ActivityDate desc

The char(13) + char(10) starts a new line in the system this string ultimately gets displayed in.  The —–‘s were used as visual separators for when the strings are all combined.

Next came the part I didn’t knowhow to do without looking, which was to combine these multiple activity strings into one big activity summary string.  I googled a bit and found this simple example and used it as mymy basic guide:

http://www.codeproject.com/Tips/334400/Concatenate-many-rows-into-a-single-text-string-us

My code came out as follows:

    -- finally, roll the strings all up into one big string representation of all the activity
    DECLARE @results nvarchar(max)
    SELECT @results = COALESCE(@results + char(13) + char(10) + '--------------------------' + char(13) + char(10) + char(13) + char(10) , '') + ActivityString FROM @ActivitiesStrings

    --SELECT @results  --debug

    -- and return the results
    if len(@results) > 0  
        set @results = @results + char(13) + char(10) + '--------------------------' + char(13) + char(10) + char(13) + char(10)
    else
        set @results = ''

    RETURN @results

Once again there are extra carriage returns and separator lines included to mimic how some other items are displayed in the target system showing this string.  Your milage may vary!  The return statement was included since this code is part of a scalar-valued user defined function I created for this purpose, and that’s how you return results from a UDF.


Scott’s recent tweets…