Search code examples
sqlsql-servert-sqlpivotunpivot

Pivot & UnPivot functionality with dates in SQL Server


I'm currently working to retrieve the last 6 available dates data using pivot, unpivot. Can anyone help me with this query?

select * 
from #myTable
unpivot (value for Area in (abc,def,fgh,ijk,klp)) up
pivot (max(value) for [date] in (
##-- Here I need to get the last 6 available dates less than current date
)) p

Datatype of [Date] column is DATE.

Sample values of date in my db

2017-09-16,
2017-09-09,
2017-09-02,
2017-08-26,
2017-07-22,
2017-07-01,
2017-06-24,
2017-06-11

Sample table, with expected result


Solution

  • Well, from your sample data, the top 6 for one area would be the same for each area since Area is the column names. With that information, we can use a dynamic unpivot after the original pivot.

    declare @table table (TheDate date, abc int, def int, fgh int, ijk int, klp int)
    insert into @table
    values
    ('20170916',1,2,34,4,5),
    ('20170909',2,3,4,5,676),
    ('20170902',6,7,8,8,9)
    
    DECLARE @DynamicPivotQuery AS NVARCHAR(MAX)
    DECLARE @ColumnName AS NVARCHAR(MAX)
    
    if object_id('tempdb..#staging') is not null drop table #staging
    
    select
        Area
        ,TheDate
        ,Val
    into #staging
    from @table
    unpivot 
        (Val for Area in (abc,def,fgh,ijk,klp)
        ) up
    
    
    --Get distinct values of the PIVOT Column / top 6 by date
    SELECT @ColumnName= ISNULL(@ColumnName + ',','') 
           + QUOTENAME(TheDate)
    FROM (SELECT DISTINCT TOP 6 TheDate FROM #staging ORDER BY TheDate DESC) AS TheDate
    
    --Prepare the PIVOT query using the dynamic 
    SET @DynamicPivotQuery = 
      N'SELECT Area, ' + @ColumnName + '
        FROM #staging
        PIVOT(SUM(Val) 
              FOR TheDate IN (' + @ColumnName + ')) AS PVTTable'
    
    --Execute the Dynamic Pivot Query
    EXEC sp_executesql @DynamicPivotQuery
    

    See It In Action Here