Search code examples
sqlsql-serverpivotdynamic-pivot

How to pivot dynamically with date as column


I have a table with product id's and names, and another table with the stock of these products on certain dates. Such as Item1 had 6 stock on 1-1-2014 and 8 stock on 2-1-2014. I'm trying to show these in a stored procedure so that it looks like a calendar, showing all the dates in a month and the stock available in the cells. What is the best way to show this?

For example:

Name  | 1-1-2014 | 2-1-2014 | 3-1-2014 | 4-1-2014
Item1 |     6    |     8    |          |    6
Item2 |          |     2    |     1    |

Original tables - Names

 ID |   Name 
  1 |  Item1
  2 |  Item2

Original tables - Stockdates

 ID | NameID  | Stock |    Date 
  1 |    1    |   8   |  2-1-2014    
  2 |    2    |   2   |  4-1-2014 

Solution

  • Here is your sample table

    SELECT * INTO #Names
    FROM
    (
    SELECT 1 ID,'ITEM1' NAME 
    UNION ALL
    SELECT 2 ID,'ITEM2' NAME 
    )TAB
    
    SELECT * INTO #Stockdates
    FROM
    (      
    SELECT 1 ID,1 NAMEID,8 STOCK,'2-1-2014 ' [DATE]
    UNION ALL
    SELECT 2 ID,2 NAMEID,2 STOCK,'4-1-2014 ' [DATE]
    )TAB
    

    Put the join data to a temperory table

    SELECT N.NAME,S.[DATE],S.STOCK 
    INTO #TABLE
    FROM #NAMES N
    JOIN #Stockdates S ON N.ID=S.NAMEID
    

    Get the columns for pivot

    DECLARE @cols NVARCHAR (MAX)
    
    SELECT @cols = COALESCE (@cols + ',[' + CONVERT(NVARCHAR, [DATE], 106) + ']', 
                   '[' + CONVERT(NVARCHAR, [DATE], 106) + ']')
                   FROM    (SELECT DISTINCT [DATE] FROM #TABLE) PV  
                   ORDER BY [DATE]
    

    Now pivot it

    DECLARE @query NVARCHAR(MAX)
    SET @query = '           
                  SELECT * FROM 
                 (
                     SELECT * FROM #TABLE
                 ) x
                 PIVOT 
                 (
                     SUM(STOCK)
                     FOR [DATE] IN (' + @cols + ')
                ) p      
    
                '     
    EXEC SP_EXECUTESQL @query
    

    And your result is here

    enter image description here