Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLite Update Syntax for Correlated Subquery with Condition

Tags:

sql

sqlite

gtfs

I'm working with GTFS data in a SQLite database. I have a StopTimes table with columns trip_id, stop_sequence, and departure_time (among others). I want to null the last departure_time (in the tuple with the largest stop_sequence) for each trip.

The most obvious way I could think of to do this was this query:

UPDATE StopTimes AS A
SET departure_time = NULL
WHERE NOT EXISTS
(
    SELECT * FROM StopTimes B
    WHERE B.stop_sequence > A.stop_sequence
)

Unfortunately, it looks like I can't use an alias for a table in an UPDATE statement in SQLite. The query fails with (in Python) "sqlite3.OperationalError: near "AS": syntax error", and this other style isn't allowed in SQLite either:

UPDATE A
SET departure_time = NULL
FROM StopTimes AS A
WHERE NOT EXISTS
(
    SELECT * FROM StopTimes B
    WHERE B.stop_sequence > A.stop_sequence
)

I've tried a couple other variants, such as using ">= ALL (SELECT stop_sequence... WHERE trip_id = ? ...)", but I can't fill in that question mark.

I've also tried this one, but it doesn't look like this is valid SQL:

UPDATE StopTimes
SET departure_time = NULL
WHERE (trip_id, stop_sequence) IN
(
    SELECT trip_id, MAX(stop_sequence)
    FROM StopTimes
    GROUP BY trip_id
)

How can I reference an outer table's attributes in a subquery in an UPDATE query, with syntax that SQLite will accept? Is there some way I can reformulate my query to get around this limitation?

like image 621
Impatient Dev Avatar asked May 12 '14 16:05

Impatient Dev


1 Answers

You cannot put an alias on the table updated in an UPDATE statement.

However, you can rename any other table in a subquery, so the table names will still be unambiguous:

UPDATE StopTimes
SET departure_time = NULL
WHERE NOT EXISTS
(
    SELECT 1 FROM StopTimes AS B
    WHERE B.stop_sequence > StopTimes.stop_sequence
)
like image 147
CL. Avatar answered Nov 08 '22 23:11

CL.