Search code examples
sqlsql-serversql-server-2008pivotunpivot

Dynamically construct static columns using pivot in SQL Server


I have a master table which doesn't contain these columns (Visit_date, M-1, M-2, M-3) but in end result I need these columns (Visit_date, M-1, M-2, M-3) along with existing master table columns such as

Retailer_id, survey_id, Group_Id, survery_Name 

I tried with pivot but can't accomplish the end result, plase suggest some with example

Master table:

 RetailerID Retailer SurveyName    Date     Score   Weights
  198760     ABC      Quality  06/03/2016   10       10
  198760     ABC      Quality  06/02/2016   5        10
  198760     ABC      Quality  06/01/2016   5        5
  198760     ABC      Quality  06/12/2015   10       10

Expected Result :

Retailer_id  survery_Name    Last_Visit    M-1    M-2    M-3   Weightage
    198760     quality          10          5       5     10     10

Script :

CREATE TABLE [dbo].[Master_Table]
(
    [Retailer_ID] [nvarchar](50) NULL,
    [RQSC_Survey_Name] [nvarchar](50) NULL,
    [RQSC_Date] [date] NULL,
    [RQSC_Weightage] [decimal](18, 0) NULL,
    [RQSC_Score] [decimal](18, 0) NULL
) ON [PRIMARY]   

INSERT [dbo].[Master_Table] ([Retailer_ID], [RQSC_Survey_Name], [RQSC_Date], [RQSC_Weightage], [RQSC_Score]) 
VALUES (N'198760', N'Quality', CAST(0x1C3B0B00 AS Date), CAST(10 AS Decimal(18, 0)), CAST(10 AS Decimal(18, 0)))

INSERT [dbo].[Master_Table] ([Retailer_ID], [RQSC_Survey_Name], [RQSC_Date], [RQSC_Weightage], [RQSC_Score]) 
VALUES (N'198760', N'Quality', CAST(0x003B0B00 AS Date), CAST(10 AS Decimal(18, 0)), CAST(5 AS Decimal(18, 0)))

INSERT [dbo].[Master_Table] ([Retailer_ID], [RQSC_Survey_Name], [RQSC_Date], [RQSC_Weightage], [RQSC_Score]) 
VALUES (N'198760', N'Quality', CAST(0xE13A0B00 AS Date), CAST(5 AS Decimal(18, 0)), CAST(5 AS Decimal(18, 0)))

INSERT [dbo].[Master_Table] ([Retailer_ID], [RQSC_Survey_Name], [RQSC_Date], [RQSC_Weightage], [RQSC_Score]) 
VALUES (N'198760', N'Quality', CAST(0xC23A0B00 AS Date), CAST(10 AS Decimal(18, 0)), CAST(10 AS Decimal(18, 0)))

My query :

SELECT
    Retailer_ID, RQSC_Survey_Name,
    [1] As LastVist, [2] as 'M-1', [3] as 'M-2', [4] as 'M-3',
    [1] as 'Score' 
FROM
    (SELECT 
         RQSC_Score, Retailer_ID, RQSC_Survey_Name, 
         RQSC_Weightage,
         ROW_NUMBER() OVER (PARTITION BY Retailer_ID ORDER BY RQSC_Date DESC) AS Rownumber 
     FROM 
         master_table 
     WHERE
         Retailer_ID = 198760 AND RQSC_Survey_Id = 298) src   
PIVOT(SUM(RQSC_Score)for Rownumber in ([1], [2], [3],[4])) piv;

Here if I select weightage column I am getting duplicate rows based upon weightage column but in expected result I should get weightage column


Solution

  • I got the solution

    WITH CTE as 
    (
    
    select retailer ,surveyname ,max([date]) 
    over(partition by retailer,surveyname)as [date],score ,weights,
    row_number() over(partition by retailer,surveyname order by [date] desc
    )
    
    as rn from #temp)  
    
    select p.retailer,p.surveyname,p.[1] as lastvisit,p.[2] as [m-1],
    p.[3] as [m-2],p.[4] as [m-3],b.score,b.weights ,b.[date] from 
    (
    
    select retailer,surveyname,score,rn from cte) as a  pivot (sum(score) 
    for rn in ([1],[2],[3],[4])
    ) as p         
    inner join cte as b on b.retailer=p.retailer and b.surveyname=p.surveyname    and b.rn=1  ;