使用内部联接删除PostgreSQL

dud*_*ude 169 sql postgresql

DELETE B.* 
FROM   m_productprice B  
       INNER JOIN m_product C ON B.m_product_id = C.m_product_id 
WHERE  C.upc = '7094' AND B.m_pricelist_version_id = '1000020'
Run Code Online (Sandbox Code Playgroud)

我收到以下错误PostgreSQL 8.2.11

ERROR:  syntax error at or near "B"
LINE 1: DELETE B.* from m_productprice B  INNER JOIN m_product C ON ...
Run Code Online (Sandbox Code Playgroud)

我试着给

DELETE B from m_productprice B  INNER JOIN m_product C ON B....
 ERROR:  syntax error at or near "B"
Run Code Online (Sandbox Code Playgroud)

我试着给

ERROR:  syntax error at or near "INNER"
LINE 1: DELETE from m_productprice B  INNER JOIN m_product C ON B.m_...
Run Code Online (Sandbox Code Playgroud)

我的查询有什么问题?

Ome*_*esh 264

DELETE 
FROM m_productprice B  
     USING m_product C 
WHERE B.m_product_id = C.m_product_id AND
      C.upc = '7094' AND                 
      B.m_pricelist_version_id='1000020';
Run Code Online (Sandbox Code Playgroud)

要么

DELETE 
FROM m_productprice
WHERE m_pricelist_version_id='1000020' AND 
      m_product_id IN (SELECT m_product_id 
                       FROM m_product 
                       WHERE upc = '7094'); 
Run Code Online (Sandbox Code Playgroud)

  • 对于较大的表,本答案中的第一个解决方案可能要快得多. (12认同)
  • 最好的答案,尤其是第一个,因为它允许您按多个字段进行匹配。 (2认同)

dud*_*ude 52

这对我有用:

DELETE from m_productprice
WHERE  m_pricelist_version_id='1000020'
       AND m_product_id IN (SELECT m_product_id
                            FROM   m_product
                            WHERE  upc = '7094'); 
Run Code Online (Sandbox Code Playgroud)


Rob*_*sey 25

与Postgres 9.1+一起使用的另一种形式是将公用表表达式与用于连接的USING语句相结合.

WITH prod AS (select m_product_id, upc from m_product where upc='7094')
DELETE FROM m_productprice B
USING prod C
WHERE B.m_product_id = C.m_product_id 
AND B.m_pricelist_version_id = '1000020';
Run Code Online (Sandbox Code Playgroud)


Iva*_*ave 21

只需使用INNER JOIN,LEFT JOIN或其他的子查询:

DELETE FROM m_productprice
WHERE m_product_id IN
(
  SELECT B.m_product_id
  FROM   m_productprice  B
    INNER JOIN m_product C 
    ON   B.m_product_id = C.m_product_id
  WHERE  C.upc = '7094' 
  AND    B.m_pricelist_version_id = '1000020'
)
Run Code Online (Sandbox Code Playgroud)

优化查询,


Mah*_*esh 13

如果您有多个联接,则可以使用逗号分隔的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)

参考

  • `a.id = b.id` 部分基本上是连接。我忽略了这一点,但这是关键部分,谢谢! (2认同)

icc*_*c97 8

基本上这里提到的所有内容都在文档中提到,但没有人具体说明具体内容。这就是当前 (v15) DELETE文档的内容:

笔记

PostgreSQL 允许您通过在子句中指定其他表来引用WHERE条件中其他表的列USING。例如,要删除给定制片人制作的所有电影,可以执行以下操作:

DELETE FROM films USING producers
 WHERE producer_id = producers.id AND producers.name = 'foo';
Run Code Online (Sandbox Code Playgroud)

这里实质上发生的是电影和制片人之间的连接,所有成功连接的电影行都被标记为删除。这种语法不是标准的。更标准的方法是:

DELETE FROM films
 WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo');
Run Code Online (Sandbox Code Playgroud)

在某些情况下,连接样式比子选择样式更容易编写或执行更快。