Skip to content
Advertisement

How do I include an additional non-aggregated column for each of my in my PIVOT values?

I have the following code fragment which gives me the current results below. I’m attempting to add an additional column for each of my pivoted values in order to include the lastview data for each of my siteuserid / tagname combo (see expected results). Since this column isn’t an aggregation, I don’t believe an additional pivot would help. I’ve tried multiple ways of adding lastview, but it always results in additional rows rather than the desired output.

create table #taghits (userid int, email varchar(20), tagname varchar(20), hits int, lastview date)

insert into #taghits select 1, 'email1@here.com', 'tag1', 3, '2020-03-24';
insert into #taghits select 2, 'email2@here.com', 'tag1', 1, '2020-03-17';
insert into #taghits select 2, 'email2@here.com', 'tag2', 1, '2020-03-18';
insert into #taghits select 3, 'email3@here.com', 'tag1', 2, '2020-03-25';
insert into #taghits select 3, 'email3@here.com', 'tag2', 5, '2020-03-28';

select * from #taghits;

DECLARE @Columns3 as NVARCHAR(MAX)
SELECT @Columns3 = ISNULL(@Columns3 + ', ','') + QUOTENAME(TagName)
FROM (
    select distinct TagName
    from #taghits
) AS TagNames
ORDER BY TagNames.TagName

DECLARE @scolumns as NVARCHAR(MAX)
SELECT @scolumns = ISNULL(@Scolumns + ', ','')+ 'ISNULL(' + QUOTENAME(TagName) + ', 0) AS '+ QUOTENAME(TagName)
FROM (select distinct TagName
    from #taghits) AS TagNames
ORDER BY TagNames.TagName

DECLARE @SQL as NVARCHAR(MAX)
SET @SQL = '
    select userid, email, ' + @scolumns + '
    from
        (
        select userid, email, tagname, hits
        from #taghits
        ) as TagHits
    PIVOT (
        SUM(hits)
        FOR TagName IN (' + @Columns3 + ')
    ) AS PivotTable
    order by userId
'

exec sp_executesql @SQL;

Current Result

| userid | email           | tag1 | tag2 |
|--------|-----------------|------|------|
| 1      | email1@here.com | 3    | 0    |
| 2      | email2@here.com | 1    | 1    |
| 3      | email3@here.com | 2    | 5    |

Desired Result

| userid | email           | tag1_hits | tag1_lastview | tag2_hits | tag2_lastview |
|--------|-----------------|-----------|---------------|-----------|---------------|
| 1      | email1@here.com | 3         | 2020-03-24    | 0         | null          |
| 2      | email2@here.com | 1         | 2020-03-17    | 1         | 2020-03-18    |
| 3      | email3@here.com | 2         | 2020-03-25    | 5         | 2020-03-28    |

Advertisement

Answer

try the following:

DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX);

SET @cols = STUFF((select distinct ', 
            SUM(CASE WHEN tagname=''' + CAST(tagname as varchar(10)) + ''' THEN [hits] ELSE 0 END) AS [' + CAST(tagname as varchar(10)) + '_hits],
            MAX(CASE WHEN tagname=''' + CAST(tagname as varchar(10)) + ''' THEN [lastview] ELSE NULL END) AS [' + CAST(tagname as varchar(10)) + '_lastview]'
            /*---------------You can add other columns here similar to above--------------*/
            FROM #taghits 
            FOR XML PATH(''),type).value('.','varchar(max)'),1,2,'')
SET @query = 'SELECT userid, email, ' + @Cols + '  FROM #taghits group by userid, email' 

print (@query)
exec(@query)

Please see db<>fiddle here.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement