Use LEAD to inspect the next scheduled value
Also published in our primary archive.
To inspect the next scheduled value in SQLite, use LEAD(at) OVER (ORDER BY at). For times 09:00, 11:00, and 15:00, it produces 11:00, 15:00, and NULL.
The naive self-join here joins every later time, not just the immediate successor. Consequently 09:00 occurs twice—once with 11:00 and once with 15:00. Adding grouping, a minimum, or more join conditions can repair that pattern, but it makes the intended adjacent-row relationship less direct. LEAD describes it explicitly: order the schedule, then look one row forward. The final row has no successor, so SQLite returns NULL; the assertion includes that boundary case.
The schema and seed list are printed so the result can be checked against the exact three-row input. SQLite specifies that LEAD returns the next row in the window partition and returns NULL when no such row exists in its window-functions documentation. The query is executed through Python’s standard-library sqlite3 module, backed only by :memory:. No newer Python-specific API is used (Python 3.5+); window functions require SQLite 3.25.0+.
AI-assistance disclosure: this synthetic example was drafted with AI assistance and is intended to be run and adapted by the reader.
import sqlite3
con = sqlite3.connect(":memory:")
con.execute("CREATE TABLE schedule(at TEXT PRIMARY KEY)")
seed = [("09:00",), ("11:00",), ("15:00",)]
con.executemany("INSERT INTO schedule VALUES (?)", seed)
print("schema:", con.execute(
"SELECT sql FROM sqlite_master WHERE name = 'schedule'"
).fetchone()[0])
print("seed:", seed)
naive = list(con.execute("""
SELECT current.at, later.at
FROM schedule AS current
LEFT JOIN schedule AS later ON later.at > current.at
ORDER BY current.at, later.at
"""))
print("naive self-join:", naive)
corrected = list(con.execute("""
SELECT at, LEAD(at) OVER (ORDER BY at) AS next_at
FROM schedule ORDER BY at
"""))
print("corrected LEAD:", corrected)
assert corrected == [
("09:00", "11:00"),
("11:00", "15:00"),
("15:00", None),
]
con.close()
schema: CREATE TABLE schedule(at TEXT PRIMARY KEY)
seed: [('09:00',), ('11:00',), ('15:00',)]
naive self-join: [('09:00', '11:00'), ('09:00', '15:00'), ('11:00', '15:00'), ('15:00', None)]
corrected LEAD: [('09:00', '11:00'), ('11:00', '15:00'), ('15:00', None)]