Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct SQLite syntax - UPDATE SELECT with WHERE EXISTS

I am trying to update a selected values in a column in a SQLite table. I only want update of the cells in the maintable where the criteria are met, and the cells must be updated to individual values, taken from a subtable.

I have tried the following syntax, but I get only a single cell update. I have also tried alternatives where all cells are updated to the first selected value of the subtable.

UPDATE maintable
SET value=(SELECT subtable.value FROM maintable, subtable
WHERE  maintable.key1=subtable.key1 AND maintable.key2=subtable.key2)
WHERE EXISTS (SELECT subtable.value FROM maintable, subtable
WHERE  maintable.key1=subtable.key1 AND maintable.key2=subtable.key2)

What is the appropriate syntax?

like image 254
AndBB Avatar asked Jun 06 '12 19:06

AndBB


People also ask

Can we use WHERE clause in UPDATE statement?

UPDATE Syntax Notice the WHERE clause in the UPDATE statement. The WHERE clause specifies which record(s) that should be updated. If you omit the WHERE clause, all records in the table will be updated!

Which of the following is the correct syntax to UPDATE data in a table in SQLite?

Syntax. Following is the basic syntax of UPDATE query with WHERE clause. UPDATE table_name SET column1 = value1, column2 = value2...., columnN = valueN WHERE [condition];

Does SQLite support select for UPDATE?

For example, MySQL supports SELECT FOR UPDATE, but SQLite does not.

How do I UPDATE multiple columns in SQLite?

First, specify the table where you want to update after the UPDATE clause. Second, set new value for each column of the table in the SET clause. Third, specify rows to update using a condition in the WHERE clause. The WHERE clause is optional.


1 Answers

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.

like image 128
Then Enok Avatar answered Sep 23 '22 19:09

Then Enok