【问题标题】:PostgreSQL: delete rows returned by subqueryPostgreSQL:删除子查询返回的行
【发布时间】:2017-07-28 08:38:52
【问题描述】:

DELETE 的基本语法是

DELETE FROM table
WHERE condition

有没有一种直接的方法在DELETE 语句中使用子查询/别名,如下所示?

DELETE FROM (subquery) as sub
WHERE condition

下面是一个最小的工作表,我尝试使用子查询/别名失败:

---create table
create table orderT (
    id integer PRIMARY KEY,
    country_code   varchar(2),
    created_date date,
    closed_date date);

---populate table
INSERT INTO orderT VALUES (1, 'US', now(), now() + interval '1 day' * 21);
INSERT INTO orderT VALUES (2, 'CA', now(), now() + interval '1 day' * 35);

--This does not work    
    DELETE
    FROM
      (SELECT *
       FROM orderT) AS sub
    WHERE sub.id = 1;

您可以试试代码here

PostgreSQL 9.5

【问题讨论】:

  • ... In my actual script, the subquery is more 90 lines long. 我的超过 300 行! -->> 请不要把你的无知隐藏在令人印象深刻的数字后面。

标签: sql postgresql subquery sql-delete


【解决方案1】:

不,您不能直接执行此操作。原因是子查询可以从多个行源构造,包括表、视图、VALUES 子句、其他子查询(由……构造)、集合返回函数……可以想象规划器可以跟踪所有表中所有受影响的行,但它根本没有实现,太复杂了。

但是,您可以构造从表中删除子查询中包含的所有行的序列,如下所示:

WITH complex_sub_query AS (
    SELECT Aid, Bid, Cid, many_more_columns
    FROM tableA
    JOIN tableB ON ...
    JOIN tableC ON ...
    ...
    WHERE complex_condition
), first_delete AS (
    DELETE FROM tableC WHERE id IN (SELECT Cid FROM complex_sub_query)
), second_delete AS (
    DELETE FROM tableB WHERE id IN (SELECT Bid FROM complex_sub_query)
)
DELETE FROM tableA WHERE id IN (SELECT Aid FROM complex_sub_query);

complex_sub_query 已具体化,因此行(包括要从中删除的表的主键)可用于以下每个DELETE 语句。由于外键、其他约束和级联删除通常与删除顺序相关,因此您必须仔细分析您的数据模型才能以正确的顺序执行操作。

【讨论】:

  • 点赞!如果你有 2 列是复合主键会发生什么
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-27
  • 2022-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多