Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disaggregate Table Over 2 Columns in T-SQL

If I have the following table

Hour    Clicks  Conversions
12:00   2   0
1:00    3   2
2:00    1   1

How do I write a SELECT statment that dissaggrates it across both columns, so I get:

12:00   1   0
12:00   1   0
1:00    1   0
1:00    1   1
1:00    1   1
2:00    1   1

If I can't do it with a SELECT, how do I write a stored proc that does it with a loop?

Thanks!

like image 587
Brad Urani Avatar asked Feb 16 '12 19:02

Brad Urani


1 Answers

This assumes there will only ever be one row for any given value of [Hour]. If there can be duplicates, I would aggregate those first (I assume the source is already an aggregation of some kind).

DECLARE @x TABLE ([Hour] CHAR(5), Clicks INT, Conversions INT);

INSERT @x SELECT '12:00',2,0
UNION ALL SELECT '13:00',3,2
UNION ALL SELECT '14:00',1,1;

;WITH x AS
(
    SELECT n = ROW_NUMBER() OVER (ORDER BY s1.[object_id]) FROM sys.all_columns AS s1
    -- CROSS JOIN (SELECT 1 UNION ALL SELECT 2) AS s2 -- to double the rows if you need more
),
y AS 
(
    SELECT [Hour], Conversions, Clicks, 
    m = MAX(CASE WHEN Conversions > Clicks THEN Conversions ELSE Clicks END) 
    FROM @x GROUP BY [Hour], Conversions, Clicks
)
SELECT y.[Hour],
    Clicks = CASE WHEN Clicks < x.n THEN 0 ELSE 1 END,
    Conversions = CASE WHEN Conversions < x.n THEN 0 ELSE 1 END
FROM x INNER JOIN y ON x.n <= y.m
ORDER BY CONVERT(TIME, y.[Hour]), Clicks, Conversions;
like image 157
Aaron Bertrand Avatar answered Oct 05 '22 08:10

Aaron Bertrand