我只是试图删除一个表中的所有行,而另一表中没有相应的行。像这样:
DELETE FROM table1 WHERE table1.pk NOT IN (SELECT fk FROM table2);
但是我一定在做一些愚蠢的事情。 SELECT
查询–查找我要删除的行–看起来很容易(并产生正确的答案),但DELETE
却使我无所适从。它要么根本无法运行,要么会删除错误的内容。
(我想到的查询在其他DBMS上也能很好地工作,但是我知道SQLite的支持更加有限。是的,我真的很熟悉SQL的工作原理……不是我的第一个牛仔竞技表演。)
有些人提出了与NOT EXISTS
有关的建议,但是我当然希望这里的那种人会回答“一个有效的查询”。我的额头会谢谢你...
答案 0 :(得分:0)
问题中的查询应该可以正常工作,除非删除导致外键约束冲突的行。
示例:
$ sqlite3
SQLite version 3.28.0 2019-04-16 19:49:53
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> create table table1(id integer);
sqlite> insert into table1 values (1),(2),(3),(4),(5);
sqlite> create table table2(id2 integer);
sqlite> insert into table2 values (1),(3),(5);
sqlite> select * from table1 where id not in (select id2 from table2);
id
----------
2
4
sqlite> delete from table1 where id not in (select id2 from table2);
sqlite> select * from table1;
id
----------
1
3
5
答案 1 :(得分:0)
仅供参考...这是有效的确切SQL查询:
delete from wagtailcore_pagerevision
where id in (select r.id from wagtailcore_pagerevision r
left join wagtailcore_page p on r.id=p.live_revision_id
where p.live_revision_id is null);
如您所见,“相当标准的LEFT JOIN
东西。”
“再次感谢您,StackOverflow!” ...现在还不确定我的“ LEFT
大脑”停在哪里……(哦,是时候喝啤酒了)。 .. :-D
答案 2 :(得分:0)
唯一的情况是此代码:
DELETE FROM wagtailcore_pagerevision
WHERE id NOT IN (SELECT live_revision_id FROM wagtailcore_page);
如果表null
的列live_revision_id
中有wagtailcore_page
个值,将不起作用。
因为如果存在空值,那么它们将包含在子查询的结果中:
SELECT live_revision_id FROM wagtailcore_page
因此,对于子查询结果中不存在的id
中的每个wagtailcore_pagerevision
,这是
IN (SELECT live_revision_id FROM wagtailcore_page)
返回null
是因为它也与null
相比较,并且NOT IN
最终返回null
,表示 unknown 或 undefined 当然不是TRUE
。
来自Comparison Functions and Operators(对于MySQL,但由于它是SQL标准,它也适用于SQLite):
为了遵守SQL标准,IN不仅会在以下情况下返回NULL: 左侧的表达式为NULL,但如果没有匹配,则为 在列表中找到,并且列表中的表达式之一为NULL。
请参见demo。
因此,解决您的问题的方法是:
DELETE FROM wagtailcore_pagerevision
WHERE id NOT IN (
SELECT live_revision_id
FROM wagtailcore_page
WHERE live_revision_id IS NOT NULL
);
请参见demo。