Summary
Generate a list of all calendar days in a given range and left‑join the Intervention rows onto it so that days without activity still appear. The trick is to create a “calendar” CTE (or temporary table) that contains every date, then perform a LEFT JOIN against the real data.
Key takeaway: Never rely on the data table to provide missing dates; generate the date series yourself.
Root Cause
- The original query selects only rows that exist in
Intervention. - SQLite (and most RDBMS) does not automatically generate rows for missing values; a
JOINcan only return rows that are present in the left‑hand side source. - Without a source that enumerates every day, there is nothing to join to fill the gaps.
Why This Happens in Real Systems
- Business reports often need a continuous time axis (e.g., daily uptime, sales per day).
- Developers assume the fact table will contain a row for every day, which is rarely true.
- The absence of a calendar dimension or a date‑generation routine leads to “holes” in time‑series outputs.
Real-World Impact
- Misleading dashboards: missing days appear as gaps rather than zero activity.
- Incorrect aggregates:
SUM,COUNT, or moving averages give lower totals because missing dates are omitted. - Customer complaints: Service Level Agreements (SLAs) that require “daily availability” cannot be proved if the report skips days.
Example or Code (if necessary and relevant)
-- 1️⃣ Generate a calendar CTE for the desired period
WITH RECURSIVE calendar(date) AS (
SELECT DATE('2026-03-01') -- start date
UNION ALL
SELECT DATE(date, '+1 day')
FROM calendar
WHERE date < DATE('2026-03-08') -- end date (inclusive)
)
-- 2️⃣ Left join the interventions onto the calendar
SELECT
c.date,
i.Technician,
i.Task
FROM calendar c
LEFT JOIN Intervention i
ON i.Date = c.date
ORDER BY c.date;
The query produces:
| Date | Technician | Task |
|---|---|---|
| 2026-03-01 | ||
| 2026-03-02 | ||
| 2026-03-03 | MA | Replace censor 25b |
| 2026-03-04 | ||
| 2026-03-05 | FM | Adjust Dielectric level |
| 2026-03-06 | MA | Empty vast container |
| 2026-03-07 | ||
| 2026-03-08 |
How Senior Engineers Fix It
- Always create a reusable calendar table or CTE for any time‑series reporting.
- Use
WITH RECURSIVE(SQLite) or a numbers table (PostgreSQL, MySQL) to generate dates on the fly. - Encapsulate the pattern in a view (
vw_DailyInterventions) so that application code never repeats the logic. - Add indexes on the
Datecolumn ofInterventionto keep the join fast, especially for large periods. - Validate the result set with a quick
COUNT(*)vs. expected number of days to catch missing rows early.
Why Juniors Miss It
- They assume the data source is complete and try to filter or aggregate directly.
- Lack of exposure to dimensional modeling concepts like a “date dimension.”
- Tend to write ad‑hoc
SELECTstatements without thinking about edge cases (e.g., holidays, weekends). - May not know SQLite supports recursive CTEs, so they look for a “magic” function that doesn’t exist.
By understanding the need for an explicit calendar source, engineers at any level can produce accurate, gap‑free time‑series reports.