12

我正在尝试更新 SQLite 表中列中的选定值。我只想更新满足条件的 maintable 中的单元格,并且必须将单元格更新为从子表中获取的单个值。

我尝试了以下语法,但我只得到一个单元格更新。我还尝试了将所有单元格更新为子表的第一个选定值的替代方法。

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)

什么是适当的语法?

4

4 回答 4

23

您可以使用 来执行此操作update select,但一次只能执行一个字段。如果 Sqlite 支持更新语句上的连接会很好,但它不支持。

这是一个相关的 SO 问题,How do I UPDATE from a SELECT in SQL Server? ,但对于 SQL Server。那里有类似的答案。

sqlite> create table t1 (id int, value1 int);
sqlite> insert into t1 values (1,0),(2,0);
sqlite> select * from t1;
1|0
2|0
sqlite> create table t2 (id int, value2 int);
sqlite> insert into t2 values (1,101),(2,102);
sqlite> update t1 set value1 = (select value2 from t2 where t2.id = t1.id) where t1.value1 = 0;
sqlite> select * from t1;
1|101
2|102
于 2014-01-16T03:24:43.783 回答
6

默认情况下,SQLite 中不存在updatewith ;joins但是我们可以使用 https://www.sqlite.org/lang_update.html 中的++来做with-clause这样的事情column-name-listselect-stmt

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;

希望 sqlite 足够聪明,不会增量查询,但根据文档它是。当使用一个选择(案例 2 和 3)设置多个列时,无效的 id(无where _id in行)将给出一个无法使用 忽略的错误ON IGNORE,案例 1 会将列设置为null(对于所有 id > 2),这也很糟糕。

于 2019-04-29T16:10:09.997 回答
6

在这种情况下,它只更新来自 maintable 的每个 raw 的 subtable 中的一个值。错误是当子表包含在 SELECT 语句中时。

UPDATE maintable
SET value=(SELECT subtable.value 
             FROM subtable
             WHERE  maintable.key1=subtable.key1 );
于 2019-01-22T22:18:34.673 回答
5

您需要使用 INSERT OR REPLACE 语句,如下所示:

假设 maintable 有 4 列:key、c​​ol2、col3、col4
并且您想用 subtable 中的匹配值更新 col3

INSERT OR REPLACE INTO maintable
SELECT maintable.key, maintable.col2, subtable.value, maintable.col4
FROM maintable 
JOIN subtable ON subtable.key = maintable.key
于 2013-03-15T04:34:47.743 回答