lesson 31 Dates, strings & subqueries · intermediate
Readable queries with CTEs
Break a query into named, readable steps.
the idea
WITH name AS (query) defines a common table expression: a named intermediate result the main query can read like a table. CTEs let you build an answer in steps, each at a clear grain, and refer to an earlier step more than once.
Dataset: U.S. Flights
The tables the challenges use, with their first 6 rows. Under each column name: the kind of value it holds, and which table it links to.
flights25 columns · 124,460 rows
| flight_idnumber · unique id | flight_datedate · links to calendar | airline_codetext · links to airlines | flight_numbernumber | tail_numbertext | origintext · links to airports | destinationtext · links to airports | route_idnumber · links to routes | scheduled_departuredate & time | actual_departuredate & time | departure_delaynumber | taxi_out_minutesnumber | scheduled_arrivaldate & time | actual_arrivaldate & time | arrival_delaynumber | air_time_minutesnumber | distance_milesnumber | cancellednumber | cancellation_codetext · links to cancellation_reasons | divertednumber | carrier_delaynumber | weather_delaynumber | nas_delaynumber | security_delaynumber | late_aircraft_delaynumber |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 2025-01-01 | AA | 2158 | N960NN | SMF | ORD | 5042 | 2025-01-01 00:25 | 2025-01-01 00:37 | 12 | 10 | 2025-01-01 06:34 | 2025-01-01 06:18 | -16 | 202 | 1781 | 0 | NULL | 0 | NULL | NULL | NULL | NULL | NULL |
| 2 | 2025-01-01 | AS | 150 | N524AS | ANC | LAX | 90 | 2025-01-01 00:44 | 2025-01-01 00:42 | -2 | 10 | 2025-01-01 07:08 | 2025-01-01 06:44 | -24 | 281 | 2345 | 0 | NULL | 0 | NULL | NULL | NULL | NULL | NULL |
| 3 | 2025-01-01 | AA | 2319 | N861NN | PHX | ORD | 4078 | 2025-01-01 00:45 | 2025-01-01 00:39 | -6 | 17 | 2025-01-01 05:16 | 2025-01-01 04:44 | -32 | 160 | 1440 | 0 | NULL | 0 | NULL | NULL | NULL | NULL | NULL |
| 4 | 2025-01-01 | UA | 2232 | N24516 | SFO | ORD | 4820 | 2025-01-01 00:59 | 2025-01-01 00:56 | -3 | 31 | 2025-01-01 07:26 | 2025-01-01 07:23 | -3 | 214 | 1846 | 0 | NULL | 0 | NULL | NULL | NULL | NULL | NULL |
| 5 | 2025-01-01 | AA | 575 | N163AA | DFW | CLT | 1457 | 2025-01-01 05:00 | 2025-01-01 04:55 | -5 | 23 | 2025-01-01 08:32 | 2025-01-01 08:14 | -18 | 105 | 936 | 0 | NULL | 0 | NULL | NULL | NULL | NULL | NULL |
| 6 | 2025-01-01 | AA | 1196 | N338ST | EWR | MIA | 1808 | 2025-01-01 05:00 | 2025-01-01 04:53 | -7 | 22 | 2025-01-01 08:20 | 2025-01-01 08:10 | -10 | 151 | 1085 | 0 | NULL | 0 | NULL | NULL | NULL | NULL | NULL |
- flight_idnumber · unique id
- 1
- flight_datedate · links to calendar
- 2025-01-01
- airline_codetext · links to airlines
- AA
- flight_numbernumber
- 2158
- tail_numbertext
- N960NN
- origintext · links to airports
- SMF
- destinationtext · links to airports
- ORD
- route_idnumber · links to routes
- 5042
- scheduled_departuredate & time
- 2025-01-01 00:25
- actual_departuredate & time
- 2025-01-01 00:37
- departure_delaynumber
- 12
- taxi_out_minutesnumber
- 10
- scheduled_arrivaldate & time
- 2025-01-01 06:34
- actual_arrivaldate & time
- 2025-01-01 06:18
- arrival_delaynumber
- -16
- air_time_minutesnumber
- 202
- distance_milesnumber
- 1781
- cancellednumber
- 0
- cancellation_codetext · links to cancellation_reasons
- NULL
- divertednumber
- 0
- carrier_delaynumber
- NULL
- weather_delaynumber
- NULL
- nas_delaynumber
- NULL
- security_delaynumber
- NULL
- late_aircraft_delaynumber
- NULL
- flight_idnumber · unique id
- 2
- flight_datedate · links to calendar
- 2025-01-01
- airline_codetext · links to airlines
- AS
- flight_numbernumber
- 150
- tail_numbertext
- N524AS
- origintext · links to airports
- ANC
- destinationtext · links to airports
- LAX
- route_idnumber · links to routes
- 90
- scheduled_departuredate & time
- 2025-01-01 00:44
- actual_departuredate & time
- 2025-01-01 00:42
- departure_delaynumber
- -2
- taxi_out_minutesnumber
- 10
- scheduled_arrivaldate & time
- 2025-01-01 07:08
- actual_arrivaldate & time
- 2025-01-01 06:44
- arrival_delaynumber
- -24
- air_time_minutesnumber
- 281
- distance_milesnumber
- 2345
- cancellednumber
- 0
- cancellation_codetext · links to cancellation_reasons
- NULL
- divertednumber
- 0
- carrier_delaynumber
- NULL
- weather_delaynumber
- NULL
- nas_delaynumber
- NULL
- security_delaynumber
- NULL
- late_aircraft_delaynumber
- NULL
- flight_idnumber · unique id
- 3
- flight_datedate · links to calendar
- 2025-01-01
- airline_codetext · links to airlines
- AA
- flight_numbernumber
- 2319
- tail_numbertext
- N861NN
- origintext · links to airports
- PHX
- destinationtext · links to airports
- ORD
- route_idnumber · links to routes
- 4078
- scheduled_departuredate & time
- 2025-01-01 00:45
- actual_departuredate & time
- 2025-01-01 00:39
- departure_delaynumber
- -6
- taxi_out_minutesnumber
- 17
- scheduled_arrivaldate & time
- 2025-01-01 05:16
- actual_arrivaldate & time
- 2025-01-01 04:44
- arrival_delaynumber
- -32
- air_time_minutesnumber
- 160
- distance_milesnumber
- 1440
- cancellednumber
- 0
- cancellation_codetext · links to cancellation_reasons
- NULL
- divertednumber
- 0
- carrier_delaynumber
- NULL
- weather_delaynumber
- NULL
- nas_delaynumber
- NULL
- security_delaynumber
- NULL
- late_aircraft_delaynumber
- NULL
- flight_idnumber · unique id
- 4
- flight_datedate · links to calendar
- 2025-01-01
- airline_codetext · links to airlines
- UA
- flight_numbernumber
- 2232
- tail_numbertext
- N24516
- origintext · links to airports
- SFO
- destinationtext · links to airports
- ORD
- route_idnumber · links to routes
- 4820
- scheduled_departuredate & time
- 2025-01-01 00:59
- actual_departuredate & time
- 2025-01-01 00:56
- departure_delaynumber
- -3
- taxi_out_minutesnumber
- 31
- scheduled_arrivaldate & time
- 2025-01-01 07:26
- actual_arrivaldate & time
- 2025-01-01 07:23
- arrival_delaynumber
- -3
- air_time_minutesnumber
- 214
- distance_milesnumber
- 1846
- cancellednumber
- 0
- cancellation_codetext · links to cancellation_reasons
- NULL
- divertednumber
- 0
- carrier_delaynumber
- NULL
- weather_delaynumber
- NULL
- nas_delaynumber
- NULL
- security_delaynumber
- NULL
- late_aircraft_delaynumber
- NULL
- flight_idnumber · unique id
- 5
- flight_datedate · links to calendar
- 2025-01-01
- airline_codetext · links to airlines
- AA
- flight_numbernumber
- 575
- tail_numbertext
- N163AA
- origintext · links to airports
- DFW
- destinationtext · links to airports
- CLT
- route_idnumber · links to routes
- 1457
- scheduled_departuredate & time
- 2025-01-01 05:00
- actual_departuredate & time
- 2025-01-01 04:55
- departure_delaynumber
- -5
- taxi_out_minutesnumber
- 23
- scheduled_arrivaldate & time
- 2025-01-01 08:32
- actual_arrivaldate & time
- 2025-01-01 08:14
- arrival_delaynumber
- -18
- air_time_minutesnumber
- 105
- distance_milesnumber
- 936
- cancellednumber
- 0
- cancellation_codetext · links to cancellation_reasons
- NULL
- divertednumber
- 0
- carrier_delaynumber
- NULL
- weather_delaynumber
- NULL
- nas_delaynumber
- NULL
- security_delaynumber
- NULL
- late_aircraft_delaynumber
- NULL
- flight_idnumber · unique id
- 6
- flight_datedate · links to calendar
- 2025-01-01
- airline_codetext · links to airlines
- AA
- flight_numbernumber
- 1196
- tail_numbertext
- N338ST
- origintext · links to airports
- EWR
- destinationtext · links to airports
- MIA
- route_idnumber · links to routes
- 1808
- scheduled_departuredate & time
- 2025-01-01 05:00
- actual_departuredate & time
- 2025-01-01 04:53
- departure_delaynumber
- -7
- taxi_out_minutesnumber
- 22
- scheduled_arrivaldate & time
- 2025-01-01 08:20
- actual_arrivaldate & time
- 2025-01-01 08:10
- arrival_delaynumber
- -10
- air_time_minutesnumber
- 151
- distance_milesnumber
- 1085
- cancellednumber
- 0
- cancellation_codetext · links to cancellation_reasons
- NULL
- divertednumber
- 0
- carrier_delaynumber
- NULL
- weather_delaynumber
- NULL
- nas_delaynumber
- NULL
- security_delaynumber
- NULL
- late_aircraft_delaynumber
- NULL
first 6 of 124,460 rows · your queries use all of them
worked example
Run these steps in order to see the idea before you write your own query. The step marked “the pattern” is what the challenges ask for. Running the example does not count toward progress.
Define a step with WITH. Run this. The CTE names daily flight counts; the outer query filters busy days.
step-1.sqlWITH daily AS ( SELECT flight_date, COUNT(*) AS flights FROM flights GROUP BY flight_date ) SELECT * FROM daily WHERE flights > 1500;
Summarize delay by route. Run this. Group operated flights by route_id and average departure_delay.
step-2.sqlSELECT route_id, COUNT(*) AS operated, ROUND(AVG(departure_delay), 1) AS avg_delay FROM flights WHERE cancelled = 0 GROUP BY route_id ORDER BY operated DESC LIMIT 10;
Put it together. The lesson's pattern in one query.the pattern
example.sqlWITH daily AS ( SELECT flight_date, COUNT(*) AS flights FROM flights GROUP BY flight_date ) SELECT * FROM daily WHERE flights > 1500;
common mistake
Averaging departure_delay over all flights includes NULLs for cancellations only implicitly. Filter to operated flights so the population is explicit.