Sqlite3:“删除... ...不在...中的位置”正确的Mojo是什么?

时间:2019-05-09 15:43:52

标签: sql sqlite

我只是试图删除一个表中的所有行,而另一表中没有相应的行。像这样:

DELETE FROM table1 WHERE table1.pk NOT IN (SELECT fk FROM table2);

但是我一定在做一些愚蠢的事情。 SELECT查询–查找我要删除的行–看起来很容易(并产生正确的答案),但DELETE却使我无所适从。它要么根本无法运行,要么会删除错误的内容。

(我想到的查询在其他DBMS上也能很好地工作,但是我知道SQLite的支持更加有限。是的,我真的很熟悉SQL的工作原理……不是我的第一个牛仔竞技表演。)

有些人提出了与NOT EXISTS有关的建议,但是我当然希望这里的那种人会回答“一个有效的查询”。我的额头会谢谢你...

3 个答案:

答案 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