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 →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| longest_streak |
|---|
| 4 |
Step by step
- 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 - 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 - 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 - 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
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 runs2. 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_date3. 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_sales4. 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 d5. 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 1Learn 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 →