sqlexcelpowerbidaxpowerquery

Power Query: Convert existing data set, individual rows into columns based on Dates


I have a data set where a customer may have had multiple assessments over a period of time. Now each customer's behavior towards these assessments may vary, meaning C1 may have had theirs on day 1, day 90, day 200, etc., and then C2 may have had their day 1, day 14, day 21, day 36, and so on.

My goal is to convert these individual rows into columns. Wonder if anyone had a similar requirement before. I am using Excel or Power Query or SQL to process this problem.

CustomerId Date Score 
C1 1/1/2020 9
C1 1/7/2020 14
C1 1/14/2020 26

C2 1/9/2020 34
C2 3/9/2020 30
C2 6/9/2020 24

Output should be in below format:

Customer | Initial Score | Avg_3_months | Avg_6_months | Avg_9_months | Avg_12_months and so on.


Solution

  • The below uses SQL Server syntax. (https://dbfiddle.uk/8WMfYXO4)

    WITH initial AS (
        SELECT CustomerId, MIN(Date) AS initial_date
        FROM data
        GROUP BY CustomerId
    )
    SELECT
        a.CustomerId,
        MAX(CASE WHEN a.Date = i.initial_date THEN a.Score END) AS Initial_Score,
        AVG(CASE WHEN a.Date > i.initial_date AND a.Date <= DATEADD(month, 3, i.initial_date) 
            THEN a.Score END) AS Avg_3m,
        AVG(CASE WHEN a.Date > DATEADD(month, 3, i.initial_date) AND a.Date <= DATEADD(month, 6, i.initial_date) 
            THEN a.Score END) AS Avg_6m,
        AVG(CASE WHEN a.Date > DATEADD(month, 6, i.initial_date) AND a.Date <= DATEADD(month, 9, i.initial_date) 
            THEN a.Score END) AS Avg_9m,
        AVG(CASE WHEN a.Date > DATEADD(month, 9, i.initial_date) AND a.Date <= DATEADD(month, 12, i.initial_date) 
            THEN a.Score END) AS Avg_12m
    FROM data a
    JOIN initial i ON a.CustomerId = i.CustomerId
    GROUP BY a.CustomerId
    ORDER BY a.CustomerId;
    

    Output:

    CustomerId Initial_Score Avg_3m Avg_6m Avg_9m Avg_12m
    C1 9 20 null null null
    C2 34 30 24 null null