Reputation: 322
Here is the input dataset I have with revenue for some of the days:
Would need an output with all dates between 03/01/2021 to 03/15/2021. $0 revenue where the value is not present
Upvotes: 0
Views: 957
Reputation: 3905
You could use two additional helper tables:
Dates
table that holds all the dates in the desired range, andZipcodes
table that holds the distinct zip codes.Instead of physical tables, temporary tables and/or table variables, you could also consider using table expressions (subqueries in the FROM-clause) or common table expressions (in a WITH-clause). Common table expressions can often also be recursive, which might be a nice solution for creating a value range with specific start and end values (like your dates range here).
It is already pointed out, that concrete solution proposals heavily depend on the target DBMS. Sadly, it is unspecified here (at the time of writing this answer). Below is a sample implementation for Microsoft SQL Server, using T
as the placeholder for your actual table name. It uses two common table expressions: a recursive CTE for the Dates
table and a normal CTE for the Zipcodes
table.
WITH
[Dates] AS (
SELECT CAST('2020-03-01' AS DATE) AS [Date]
UNION ALL
SELECT DATEADD(DAY, 1, [Date])
FROM [Dates]
WHERE [Date] < '2020-03-15'
),
[ZipCodes] AS (
SELECT DISTINCT [Zip] FROM T
)
SELECT D.[Date], Z.[Zip], COALESCE(T.[Revenue], 0) AS [Revenue]
FROM
[Dates] AS D
CROSS JOIN [ZipCodes] AS Z
LEFT JOIN T ON T.[Date] = D.[Date] AND T.[Zip] = Z.[Zip]
ORDER BY Z.[Zip], D.[Date]
Upvotes: 1
Reputation: 733
You haven't specified your RDBMS, it's probably going to be implemented differently in different systems. E.g. in the SQL Server there's a master.dbo.spt_values
table, which can potentially be used for that:
SELECT DATEADD(day, d.number, '2021-03-01') as Date,
zips.Zip,
IsNull(t.Revenue, 0) as Revenue
FROM master.dbo.spt_values d
CROSS JOIN (SELECT DISTINCT(Zip) FROM Table) zips
LEFT JOIN Table t
ON DATEADD(day, d.number, '2021-03-01') = t.Date
AND zips.Zip = t.Zip
WHERE d.type = 'P'
AND d.number < 15
ORDER BY zips.Zip, d.number
It's somewhat of a hack though
Upvotes: 0