By default update
with joins
does not exist in SQLite; But we can use the with-clause
+ column-name-list
+ select-stmt
from https://www.sqlite.org/lang_update.html to make something like this:
CREATE TABLE aa (
_id INTEGER PRIMARY KEY,
a1 INTEGER,
a2 INTEGER);
INSERT INTO aa VALUES (1,10,20);
INSERT INTO aa VALUES (2,-10,-20);
INSERT INTO aa VALUES (3,0,0);
--a bit unpleasant because we have to select manually each column and it's just a lot to write
WITH bb (_id,b1, b2)
AS (SELECT _id,a1+2, a2+1 FROM aa WHERE _id<=2)
UPDATE aa SET a1=(SELECT b1 FROM bb WHERE bb._id=aa._id),a2=(SELECT b2 FROM bb WHERE bb._id=aa._id)
WHERE _id in (SELECT _id from bb);
--soo now it should be (1,10,20)->(1,12,21) and (2,-10,-20)->(2,-8,-19), and it is
SELECT * FROM aa;
--even better with one select for each row!
WITH bb (_id,b1, b2)
AS (SELECT _id,a1+2, a2+1 from aa WHERE _id<=2)
UPDATE aa SET (a1,a2)=(SELECT b1,b2 FROM bb WHERE bb._id=aa._id)
WHERE _id in (SELECT _id from bb);
--soo now it should be (1,12,21)->(1,14,22) and (2,-8,-19)->(2,-6,-18), and it is
SELECT * FROM aa;
--you can skip the WITH altogether
UPDATE aa SET (a1,a2)=(SELECT bb.a1+2, bb.a2+1 FROM aa AS bb WHERE aa._id=bb._id)
WHERE _id<=2;
--soo now it should be (1,14,22)->(1,16,23) and (2,-6,-18)->(2,-4,-17), and it is
SELECT * FROM aa;
Hopefully sqlite is smart enough to not query incrementally but according to the documentation it is. When setting multiple columns using one select (case 2 and 3) a not valid id (no where _id in
line) will give an error that can not be ignored using ON IGNORE
, case 1 will set columns to null
(for all ids >2) which is also bad.