删除其他表中未引用的行


15

我在PostgreSQL 9.3数据库中有两个表:表link_reply有一个名为which_group指向table 的外键link_group

我要删除link_grouplink_reply存在相关行的所有行。听起来很基本,但我一直在努力。

这样简单吗(不起作用)?

DELETE FROM link_group WHERE link_reply = NULL;

您有供所有人查看的DDL吗?
dizzystar '16

看一下MINUS运算符。您必须在links_reply中指定一个字段。
Vérace

DELETE FROM links_group USING links_group AS lg LEFT JOIN links_reply AS lr ON lg.col= lr.some_other_col WHERE links_reply.some_other_col IS NULL
Mihai 2016年

我有一个类似的问题,它也考虑了并发性。请参阅dba.stackexchange.com/questions/251875
pbillen

Answers:


19

引用手册:

使用数据库中其他表中包含的信息删除表中的行有两种方法:使用子选择,或在USING子句中指定其他表。哪种技术更合适取​​决于具体情况。

大胆强调我的。使用另一个表中包含的信息有些棘手,但是有一些简单的解决方案。从标准技术库到...

...对于以下情况,NOT EXISTS反半联接可能是最简单,最有效的DELETE

DELETE FROM link_group lg
WHERE  NOT EXISTS (
   SELECT FROM link_reply lr
   WHERE  lr.which_group = lg.link_group_id
   );

假设(由于未提供表定义)link_group_id作为的主键的列名link_group

@Mihai评论的技术也可以(正确应用):

DELETE FROM link_group lg
USING  link_group      lg1
LEFT   JOIN link_reply lr ON lr.which_group = lg1.link_group_id
WHERE  lg1.link_group_id = lg.link_group_id
AND    lr.which_group IS NULL;

但是,由于USING子句中的表表达式lg使用a 联接到目标表(在示例中)CROSS JOIN,因此您需要使用与踏脚石(lg1在示例中)相同的表的另一个实例LEFT JOIN,它不太优雅,并且通常较慢。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.