lesson 39 Window functions · advanced
Compare rows with LAG
Compare each row with an earlier row.
the idea
LAG(column) returns the value from the previous row in the window order; LEAD returns the next. With PARTITION BY tail_number ORDER BY scheduled_departure, the previous row is the same aircraft’s previous flight, so you can compare consecutive legs.
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.
Look at the previous leg. Run this. LAG() pulls the prior row’s destination for the same tail number—handy for spotting whether origin matches where the plane last landed.
step-1.sqlSELECT flight_id, tail_number, origin, destination, LAG(destination) OVER (PARTITION BY tail_number ORDER BY scheduled_departure, flight_id) AS previous_destination FROM flights WHERE flight_date = '2025-01-15' AND tail_number IS NOT NULL LIMIT 20;
Compare delay to the last arrival. Run this. For each operated flight you see this leg’s departure delay beside the previous leg’s arrival delay on that aircraft. The first leg of the day shows NULL for the lag column.
step-2.sqlSELECT flight_id, tail_number, departure_delay, LAG(arrival_delay) OVER (PARTITION BY tail_number ORDER BY scheduled_departure, flight_id) AS previous_arrival_delay FROM flights WHERE flight_date = '2025-01-15' AND cancelled = 0 AND tail_number IS NOT NULL LIMIT 20;
Put it together. The lesson's pattern in one query.the pattern
example.sqlSELECT flight_id, tail_number, origin, destination, LAG(destination) OVER (PARTITION BY tail_number ORDER BY scheduled_departure, flight_id) AS previous_destination FROM flights WHERE flight_date = '2025-01-15' AND tail_number IS NOT NULL;
common mistake
The first row of each partition has no previous row: LAG returns NULL, not zero. Local times are only comparable at the same airport, which is exactly where an aircraft arrives and departs again.