sqlsql-serverdynamic-pivot

Create a dynamic pivot like the example shown


This is my sample raw data:

Ref_date Ref_source
6/12/2024 A
6/13/2024 A
6/14/2024 B
6/15/2024 B

How do I get an output that mirrors the following:

I'd like for it to be dynamic per year, month, qtr. The qtr must be aggregated like the month via a count.

screenshot


Solution

  • Month and quarter counts by Ref_source

    SELECT Ref_Source, year(Ref_date) as [Year], 
        SUM(CASE Month(Ref_date) WHEN 1 THEN 1 ELSE 0 END) as Jan, 
        SUM(CASE Month(Ref_date) WHEN 2 THEN 1 ELSE 0 END) as Feb ,
        SUM(CASE Month(Ref_date) WHEN 3 THEN 1 ELSE 0 END) as Mar,
        SUM(CASE WHEN Month(Ref_date) Between 1 AND 3 THEN 1 ELSE 0 END) as Q1,
        SUM(CASE Month(Ref_date) WHEN 4 THEN 1 ELSE 0 END) as Apr ,
        SUM(CASE Month(Ref_date) WHEN 5 THEN 1 ELSE 0 END) as May ,
        SUM(CASE Month(Ref_date) WHEN 6 THEN 1 ELSE 0 END) as June ,
        SUM(CASE WHEN Month(Ref_date) Between 4 AND 6 THEN 1 ELSE 0 END) as Q2,
        SUM(CASE Month(Ref_date) WHEN 7 THEN 1 ELSE 0 END) as July ,
        SUM(CASE Month(Ref_date) WHEN 8 THEN 1 ELSE 0 END) as Aug ,
        SUM(CASE Month(Ref_date) WHEN 9 THEN 1 ELSE 0 END) as Sep,
        SUM(CASE WHEN Month(Ref_date) Between 7 AND 9 THEN 1 ELSE 0 END) as Q3,
         SUM(CASE Month(Ref_date) WHEN 10 THEN 1 ELSE 0 END) as Oct, 
        SUM(CASE Month(Ref_date) WHEN 11 THEN 1 ELSE 0 END) as Nov ,
        SUM(CASE Month(Ref_date) WHEN 12 THEN 1 ELSE 0 END) as Dec,
        SUM(CASE WHEN Month(Ref_date) Between 10 AND 12 THEN 1 ELSE 0 END) as Q4
    FROM Example
    GROUP BY ref_source, year(Ref_date)
    

    fiddle

    Ref_Source Year Jan Feb Mar Q1 Apr May June Q2 July Aug Sep Q3 Oct Nov Dec Q4
    A 2024 0 0 0 0 0 0 2 2 0 0 0 0 0 0 0 0
    B 2024 0 0 0 0 0 0 2 2 0 0 0 0 0 0 0 0