Reputation: 21
I have a long list of accounts with date ranges and costs, here are two rows for example:
Account Start_date End_date Cost
Megadeal 11/6/2015 13/6/2015 1000$
Superstar 12/8/2014 14/8/2014 2000$
And I need to populate a list with all the dates in each range, one row for each day, and each day with the name of the account and cost. The result should look something like that:
Megadeal 11/6/2015 1000
Megadeal 12/6/2015 1000
Megadeal 13/6/2015 1000
Superstar 12/8/2014 2000
Superstar 13/8/2014 2000
Superstar 14/8/2014 2000
Meaning to populate the list of dates from a different range every time (different start date and end date).
Any advice?
Upvotes: 1
Views: 57
Reputation: 31879
You can use a Tally Table to generate the dates:
DECLARE @maxDiff INT;
SELECT @maxDiff = MAX(DATEDIFF(DAY, Start_Date, End_Date)) FROM tbl;
WITH E1(N) AS( -- 10 ^ 1 = 10 rows
SELECT 1 FROM(VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))t(N)
),
E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b), -- 10 ^ 2 = 100 rows
E4(N) AS(SELECT 1 FROM E2 a CROSS JOIN E2 b), -- 10 ^ 4 = 10,000 rows
E8(N) AS(SELECT 1 FROM E4 a CROSS JOIN E4 b), -- 10 ^ 8 = 10,000,000 rows
CteTally(N) AS(
SELECT TOP(@maxDiff + 1) ROW_NUMBER() OVER(ORDER BY(SELECT NULL))
FROM E8
)
SELECT
t.Account,
Date = DATEADD(DAY, ct.N - 1, t.Start_Date),
t.Cost
FROM tbl t
CROSS JOIN CteTally ct
WHERE DATEADD(DAY, ct.N - 1, t.Start_Date) <= t.End_Date
ORDER BY t.Account, Date;
Upvotes: 2