SQL pivot table grouping

Michael M.M. D'Angelo 176 Reputation points
2022-03-01T17:09:15.607+00:00

I have the below table structure
178887-image.png

With data like below

178896-image.png

I want a pivot table that will look like the below in rdl reporting server

178948-image.png

Developer technologies Transact-SQL
{count} votes

Accepted answer
  1. LiHong-MSFT 10,056 Reputation points
    2022-03-02T08:12:48.253+00:00

    Hi @Michael M.M. D'Angelo
    There several ways to this issue:
    First: Use aggregate functions along with Case when,just as Naomi answered.However this method need to write multiple lines of code.

    Second: Use Cross Apply and Pivot,like this:

    ;WITH CTE AS  
    (  
     SELECT R.ClientID,R.Years,U.*  
     FROM Rhema_GoldExportSummary R  
     CROSS APPLY(VALUES(TotalGrossWeight,SUBSTRING([Month],1,3)+'_TotalGrossWeight'),  
                       (TotalGoldNetWeightOZ,SUBSTRING([Month],1,3)+'_TotalGoldNetWeightOZ'),  
    				   (TotalSilverNetWeightOZ,SUBSTRING([Month],1,3)+'_TotalSilverNetWeightOZ'),  
    				   (TotalGoldSilverValueFunctional,SUBSTRING([Month],1,3)+'_TotalGoldSilverValueFunctional')) AS U(VALUE,TITLE)  
    )  
    SELECT * FROM CTE  
    PIVOT(MAX(VALUE)FOR TITLE IN([Jan_TotalGrossWeight],[Jan_TotalGoldNetWeightOZ],[Jan_TotalSilverNetWeightOZ],[Jan_TotalGoldSilverValueFunctional],  
                                 [Feb_TotalGrossWeight],[Feb_TotalGoldNetWeightOZ],[Feb_TotalSilverNetWeightOZ],[Feb_TotalGoldSilverValueFunctional],  
    							 [Mar_TotalGrossWeight],[Mar_TotalGoldNetWeightOZ],[Mar_TotalSilverNetWeightOZ],[Mar_TotalGoldSilverValueFunctional],  
    							 [Apr_TotalGrossWeight],[Apr_TotalGoldNetWeightOZ],[Apr_TotalSilverNetWeightOZ],[Apr_TotalGoldSilverValueFunctional],  
    							 [May_TotalGrossWeight],[May_TotalGoldNetWeightOZ],[May_TotalSilverNetWeightOZ],[May_TotalGoldSilverValueFunctional],  
    							 [Jun_TotalGrossWeight],[Jun_TotalGoldNetWeightOZ],[Jun_TotalSilverNetWeightOZ],[Jun_TotalGoldSilverValueFunctional],  
    							 [Jul_TotalGrossWeight],[Jul_TotalGoldNetWeightOZ],[Jul_TotalSilverNetWeightOZ],[Jul_TotalGoldSilverValueFunctional],  
    							 [Aug_TotalGrossWeight],[Aug_TotalGoldNetWeightOZ],[Aug_TotalSilverNetWeightOZ],[Aug_TotalGoldSilverValueFunctional],  
    							 [Sep_TotalGrossWeight],[Sep_TotalGoldNetWeightOZ],[Sep_TotalSilverNetWeightOZ],[Sep_TotalGoldSilverValueFunctional],  
    							 [Oct_TotalGrossWeight],[Oct_TotalGoldNetWeightOZ],[Oct_TotalSilverNetWeightOZ],[Oct_TotalGoldSilverValueFunctional],  
    							 [Nov_TotalGrossWeight],[Nov_TotalGoldNetWeightOZ],[Nov_TotalSilverNetWeightOZ],[Nov_TotalGoldSilverValueFunctional],  
    							 [Dec_TotalGrossWeight],[Dec_TotalGoldNetWeightOZ],[Dec_TotalSilverNetWeightOZ],[Dec_TotalGoldSilverValueFunctional]))P  
    

    Third:Use dynamic SQL to get column names,like this:

    DECLARE @COLUMN_NAME VARCHAR(MAX)  
    DECLARE @SQL VARCHAR(MAX)  
    ;WITH CTE AS  
    (SELECT R.*,U.*  
     FROM Rhema_GoldExportSummary R  
     CROSS APPLY(VALUES(TotalGrossWeight,SUBSTRING([Month],1,3)+'_TotalGrossWeight'),  
                       (TotalGoldNetWeightOZ,SUBSTRING([Month],1,3)+'_TotalGoldNetWeightOZ'),  
    				   (TotalSilverNetWeightOZ,SUBSTRING([Month],1,3)+'_TotalSilverNetWeightOZ'),  
    				   (TotalGoldSilverValueFunctional,SUBSTRING([Month],1,3)+'_TotalGoldSilverValueFunctional')) AS U(VALUE,TITLE)  
     WHERE ClientID=40  
    )  
    SELECT @COLUMN_NAME = ISNULL(@COLUMN_NAME + ',','') +QUOTENAME(TITLE)   
    FROM CTE ORDER BY ID  
    --PRINT @COLUMN_NAME  
    SET @SQL = '  
    WITH CTE AS  
    (  
     SELECT R.ClientID,R.Years,U.*  
     FROM Rhema_GoldExportSummary R  
     CROSS APPLY(VALUES(TotalGrossWeight,SUBSTRING([Month],1,3)+''_TotalGrossWeight''),  
                       (TotalGoldNetWeightOZ,SUBSTRING([Month],1,3)+''_TotalGoldNetWeightOZ''),  
    				   (TotalSilverNetWeightOZ,SUBSTRING([Month],1,3)+''_TotalSilverNetWeightOZ''),  
    				   (TotalGoldSilverValueFunctional,SUBSTRING([Month],1,3)+''_TotalGoldSilverValueFunctional'')) AS U(VALUE,TITLE)  
    )  
    SELECT * FROM CTE  
    PIVOT(MAX(VALUE)FOR TITLE IN('+ @COLUMN_NAME +'))P'  
    PRINT @SQL  
    EXEC (@SQL)  
    

    Best regards,
    LiHong


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our Documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Naomi Nosonovsky 8,431 Reputation points
    2022-03-01T18:10:55.58+00:00

    Do you want to have 12 big columns (for each month of the year) always or you may want to that 12 to be conditional if the year is in the middle?

    For the former there is a T-SQL case based pivot which I normally use. Since you have 4 weights, you would have 48 expressions in your query.

    You can also construct it dynamically.

    https://social.technet.microsoft.com/wiki/contents/articles/17510.t-sql-dynamic-pivot-on-multiple-columns.aspx

    1 person found this answer helpful.

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.