BBampaa

Lessons › SQL › Deep Dive: Business Analytics Patterns

SQL lesson

GENERATE_SERIES() for date ranges and gap filling

GENERATE_SERIES() for dates produces every date in a range - including days where nothing happened - so gaps never silently disappear from your results.

Try this lesson free →
About 5–10 minutes · no sign-up needed

Example

Filling Retail Date Gaps with GENERATE_SERIES()

WITH date_spine AS (
  SELECT generate_series('2024-03-01'::date, '2024-03-08'::date, '1 day'::interval)::date AS order_date
)
SELECT ds.order_date,
       COALESCE(SUM(o.revenue), 0) AS total_revenue,
       COALESCE(SUM(o.units_sold), 0) AS total_units
FROM date_spine ds
LEFT JOIN orders o ON o.order_date = ds.order_date
GROUP BY ds.order_date
ORDER BY ds.order_date

Result:

order_datetotal_revenuetotal_units
2024-03-011240.534
2024-03-02980.027
2024-03-0300
2024-03-0400
2024-03-051530.7541
2024-03-06670.2518

Step by step

  1. WITH lets you name a sub-query so the main query can reference it.
    WITH date_spine AS (
      SELECT generate_series('2024-03-01'::date, '2024-03-08'::date, '1 day'::interval)::date AS order_date
    )
  2. After SELECT, list the column names you want, separated by commas.
    WITH date_spine AS (
      SELECT generate_series('2024-03-01'::date, '2024-03-08'::date, '1 day'::interval)::date AS order_date
    )
    SELECT ds.order_date,
           COALESCE(SUM(o.revenue), 0) AS total_revenue,
           COALESCE(SUM(o.units_sold), 0) AS total_units
  3. FROM tells SQL which table to pull the data from.
    WITH date_spine AS (
      SELECT generate_series('2024-03-01'::date, '2024-03-08'::date, '1 day'::interval)::date AS order_date
    )
    SELECT ds.order_date,
           COALESCE(SUM(o.revenue), 0) AS total_revenue,
           COALESCE(SUM(o.units_sold), 0) AS total_units
    FROM date_spine ds

Practice

Try each one in your head first, then open the answer.

1. Write a query that uses GENERATE_SERIES to produce every date from '2024-01-01' to '2024-12-31' stepping by 1 day.
SELECT GENERATE_SERIES('2024-01-01'::date, '2024-12-31'::date, INTERVAL '1 day')
2. Write a query that uses GENERATE_SERIES to produce every date from '2024-01-01' to '2024-12-31' stepping by 1 day.
SELECT GENERATE_SERIES('2024-01-01'::date, '2024-12-31'::date, INTERVAL '1 day')
3. Write a query that uses GENERATE_SERIES to produce every date from '2024-01-01' to '2024-12-31' stepping by 1 day.
SELECT GENERATE_SERIES('2024-01-01'::date, '2024-12-31'::date, INTERVAL '1 day')
4. Write a query that uses GENERATE_SERIES to produce every date from '2024-01-01' to '2024-12-31' stepping by 1 day.
SELECT GENERATE_SERIES('2024-01-01'::date, '2024-12-31'::date, INTERVAL '1 day')
5. Write a query that uses GENERATE_SERIES to produce every date from '2024-01-01' to '2024-12-31' stepping by 1 day.
SELECT GENERATE_SERIES('2024-01-01'::date, '2024-12-31'::date, INTERVAL '1 day')

Learn it by doing. This lesson is a short hands-on level on Bampaa: see it work, then build and write it yourself, with instant feedback.

Try this lesson free →
About 5–10 minutes · no sign-up needed