lesson 15 Calculations & data quality · intermediate
Conditional aggregation
Calculate several conditional metrics in one summary.
the idea
Conditional aggregation puts a CASE inside an aggregate so one grouped query can count several categories side by side. SUM(CASE WHEN condition THEN 1 ELSE 0 END) counts the rows that meet the condition.
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.
See cancelled vs operated flights. Run this. Cancelled flights have NULL departure_delay; operated flights show a delay in minutes.
step-1.sqlSELECT flight_id, airline_code, cancelled, departure_delay FROM flights WHERE flight_date = '2025-01-10' LIMIT 15;
Count diversions in each airline column. Run this. SUM(CASE WHEN …) adds one per diverted flight within each airline group.the pattern
example.sqlSELECT airline_code, SUM(CASE WHEN diverted = 1 THEN 1 ELSE 0 END) AS diverted FROM flights GROUP BY airline_code;
common mistake
A cancelled flight has no departure delay. Treating NULL as on time overstates punctuality; restrict on-time counts to operated flights.