从 INNER JOINed 3 个不同表中删除所有行

SNa*_*aRe 3 postgresql performance postgresql-10 query-performance

我有一个疑问。我想删除这 3 个不同表中的所有选定行 由于我有很多 INNER 连接,我无法弄清楚。我的目标是删除这些卖家 ID 的所有内容。

SELECT *
FROM orders a
 INNER JOIN order_items b ON a.order_id = b.order_id
 INNER JOIN order_item_histories c ON c.order_item_id = b.order_item_id
WHERE a.seller_id IN (1, 3)
Run Code Online (Sandbox Code Playgroud)

版本 Postgres 10.3

我试过这个,但我无法成功。

DELETE
FROM  
   USING orders
   USING order_items,
   USING order_item_histories
WHERE orders.order_id = order_items.order_id AND order_items.order_item_id = order_item_histories.order_item_id
AND  orders.seller_id IN (1, 3)
Run Code Online (Sandbox Code Playgroud)

Mah*_*esh 7

如果您有多个连接,您可以使用逗号分隔的 USING 语句:

DELETE 
FROM 
      AAA AS a 
USING 
      BBB AS b,
      CCC AS c
WHERE 
      a.id = b.id 
  AND a.id = c.id
  AND a.uid = 12345 
  AND c.gid = 's434sd4'
Run Code Online (Sandbox Code Playgroud)

参考

  • 可能没有选择作为答案,因为这不会从所有三个表中删除,但是这种包含 3 个不同语句的方法会更优雅 (3认同)
  • 这对我很有用,因为我正在寻找多个连接,哈哈 (2认同)

ype*_*eᵀᴹ 5

一个DELETE语句只能从一个表中删除(除非有触发器或外键ON DELETE CASCADE定义选项的)。

为了解决这个问题,您可以使用 3 个DELETE语句:

DELETE FROM order_item_histories
WHERE order_item_id IN
      ( SELECT b.order_item_id 
        FROM order_items AS b
             JOIN orders AS a
               ON a.order_id = b.order_id
        WHERE a.seller_id IN (1, 3)
      )
RETURNING order_item_id, order_item_history_id ;

DELETE FROM order_items 
WHERE order_id IN 
      ( SELECT order_id
        FROM orders
        WHERE seller_id IN (1, 3)
      )
RETURNING order_id, order_item_id ;

DELETE FROM orders
WHERE seller_id IN (1, 3)
RETURNING order_id ;
Run Code Online (Sandbox Code Playgroud)

或通过链接(数据修改)CTE:

WITH 
  a AS 
  ( DELETE FROM orders
    WHERE seller_id IN (1, 3)
    RETURNING order_id
  ),
  b AS
  ( DELETE FROM order_items 
    WHERE order_id IN (SELECT order_id FROM a)
    RETURNING order_id, order_item_id 
  ),
  c AS
  ( DELETE FROM order_item_histories
    WHERE order_item_id IN (SELECT order_item_id FROM b)
    RETURNING order_item_id, order_item_history_id
  )
SELECT
    a.order_id,
    b.order_item_id, 
    c.order_item_history_id
FROM a
  LEFT JOIN b ON a.order_id = b.order_id
  LEFT JOIN c ON c.order_item_id = b.order_item_id ;
Run Code Online (Sandbox Code Playgroud)