PostgreSQL:删除子查询返回的行

时间:2017-03-07 23:15:08

标签: sql postgresql subquery sql-delete

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;

您可以尝试代码CODEPEN DEMO

PostgreSQL 9.5

1 个答案:

答案 0 :(得分:3)

不,你不能直接这样做。原因是子查询可以从多个行源构建,包括表,视图,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语句。由于删除顺序通常与外键,其他约束和级联删除相关,因此您必须仔细分析数据模型,以便按正确的顺序执行操作。