BBampaa

Lessons › SQL › Go further in SQL: Business questions

SQL lesson

What's our longest run of days with a sale?

What's the longest run of days in a row with at least one sale? The trick: number the days 1, 2, 3… in date order. For days in a row, the date minus its number stays the same; after a gap, it jumps. So that difference labels each run. Count the days in each run and keep the longest.

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

Example

Gaps and islands: days in a row share a gap from their row number

WITH d AS (
  SELECT sale_date,
         sale_date
           - CAST(ROW_NUMBER() OVER (ORDER BY sale_date) AS INT) AS grp
  FROM daily_sales
), runs AS (
  SELECT grp, COUNT(*) AS days
  FROM d
  GROUP BY grp
)
SELECT MAX(days) AS longest_streak
FROM runs

Result:

longest_streak
4

Step by step

  1. The longest run of days in a row.
    WITH d AS (SELECT sale_date, sale_date - CAST(ROW_NUMBER() OVER (ORDER BY sale_date) AS INT) AS grp FROM daily_sales), runs AS (SELECT grp, COUNT(*) AS days FROM d GROUP BY grp) SELECT MAX(days) AS longest_streak FROM runs
  2. One row per day with a sale.
    WITH d AS (SELECT sale_date, sale_date - CAST(ROW_NUMBER() OVER (ORDER BY sale_date) AS INT) AS grp FROM daily_sales), runs AS (SELECT grp, COUNT(*) AS days FROM d GROUP BY grp) SELECT MAX(days) AS longest_streak FROM runs
  3. Every day counts.
    WITH d AS (SELECT sale_date, sale_date - CAST(ROW_NUMBER() OVER (ORDER BY sale_date) AS INT) AS grp FROM daily_sales), runs AS (SELECT grp, COUNT(*) AS days FROM d GROUP BY grp) SELECT MAX(days) AS longest_streak FROM runs
  4. Date minus ROW_NUMBER is the same for every day in a run.
    WITH d AS (SELECT sale_date, sale_date - CAST(ROW_NUMBER() OVER (ORDER BY sale_date) AS INT) AS grp FROM daily_sales), runs AS (SELECT grp, COUNT(*) AS days FROM d GROUP BY grp) SELECT MAX(days) AS longest_streak FROM runs

Practice

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

1. What's the longest run of days in a row with at least one sale? Show one number, longest_streak.
WITH d AS (SELECT sale_date, sale_date - CAST(ROW_NUMBER() OVER (ORDER BY sale_date) AS INT) AS grp FROM daily_sales), runs AS (SELECT grp, COUNT(*) AS days FROM d GROUP BY grp) SELECT MAX(days) AS longest_streak FROM runs
2. Show every run of days in a row with a sale: when it started, when it ended and how many days. Show start_date, end_date and days.
WITH d AS (SELECT sale_date, sale_date - CAST(ROW_NUMBER() OVER (ORDER BY sale_date) AS INT) AS grp FROM daily_sales) SELECT MIN(sale_date) AS start_date, MAX(sale_date) AS end_date, COUNT(*) AS days FROM d GROUP BY grp ORDER BY start_date
3. Number the sale days 1, 2, 3… in date order. Show sale_date and day_no.
SELECT sale_date, ROW_NUMBER() OVER (ORDER BY sale_date) AS day_no FROM daily_sales
4. How many separate runs of days in a row are there? Show one number, runs.
WITH d AS (SELECT sale_date - CAST(ROW_NUMBER() OVER (ORDER BY sale_date) AS INT) AS grp FROM daily_sales) SELECT COUNT(DISTINCT grp) AS runs FROM d
5. When did the longest run start? Show start_date and days.
WITH d AS (SELECT sale_date, sale_date - CAST(ROW_NUMBER() OVER (ORDER BY sale_date) AS INT) AS grp FROM daily_sales), runs AS (SELECT MIN(sale_date) AS start_date, COUNT(*) AS days FROM d GROUP BY grp) SELECT start_date, days FROM runs ORDER BY days DESC LIMIT 1

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