How to pivot dynamically with date as column

后端 未结 2 428
再見小時候
再見小時候 2020-12-02 00:01

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

相关标签:
2条回答
  • 2020-12-02 00:32

    Step 1 - Fill the gaps (maybe not required)

    If your stocks table does not contain stock from every day for every product then you have to get all the dates in a month from somewhere else. You can generate them with a recursive CTE: (variable declarations are omitted)

    with dates as
    (
       select @startdate as [date]
       union ALL
       select   [date] + 1 
       from dates
       where    [date] < @enddate
    )
    select  @strDays = COALESCE(@strDays + ', ['+ convert(varchar(8), [date],112) + ']', '['+ convert(varchar(8), [date],112) + ']') 
    from    dates;
    

    You can use your preferred date format but it's important to maintain it in all queries.

    Step 2 - Bring data to a normal form. You can chose to store it in a temporary table or you can use a CTE again and combine this step with step 3.

    Join dates (from above) with products (full) and with stock (left) so you obtain a table like this:

    date
    product_id    
    items
    

    For products and dates where stock is not available you display 0. isnull will do the trick. Make sure the date column is converted to varchar in the same format as in CTE above.

    Step 3 - pivot the table (obtained at step 2) by date column in a dynamic query.

    I can give you more details but not right now. You can see something similar in another response: Spread distinct values over different columns

    0 讨论(0)
  • 2020-12-02 00:35

    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

    0 讨论(0)
提交回复
热议问题