【问题标题】:PostgreSQL delete with inner joinPostgreSQL 使用内部连接删除
【发布时间】:2012-07-30 00:48:38
【问题描述】:
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'

我收到以下错误 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 ...

我试着给

DELETE B from m_productprice B  INNER JOIN m_product C ON B....
 ERROR:  syntax error at or near "B"

我试着给予

ERROR:  syntax error at or near "INNER"
LINE 1: DELETE from m_productprice B  INNER JOIN m_product C ON B.m_...

我的查询有什么问题?

【问题讨论】:

  • 8.2?您应该尽快升级。该版本不再受支持。请阅读手册:没有可用于 DELETE 语句的INNER JOINpostgresql.org/docs/8.2/static/sql-delete.html
  • 在没有内部连接的情况下执行此查询的任何替代方法
  • 查看手册,有一个例子。
  • @a_horse_with_no_name 在当前的 8.2 文档中,它没有明确声明您不能将 JOINDELETE 一起使用。它建议使用他们的替代非标准USING 语法,否则建议使用WHERE,但它没有提到不支持JOIN 的任何地方。鉴于在 MySQL 和 SQL Server 中允许 DELETE 子句中的 JOIN,Postgres 是一个奇怪的结果。也许他们有他们的理由,但他们应该明确postgresql.org/docs/8.2/sql-delete.html
  • 8.2 不是 "current" documentation。语法图仅记录可用选项。因此,自动不支持语法图中包含的任何选项not。 SQL 标准不包括在 DELETE 语句中“连接”表的任何选项。所以 Postgres 的 USING 选项与 MySQL 和 SQL Server 使用的 JOIN 选项一样非标准。他们都没有定义“标准”,例如Oracle 和 DB2 根本没有“加入”其他表的选项

标签: sql postgresql


【解决方案1】:

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

Reference

【讨论】:

    【解决方案2】:

    只需使用带有 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'
    )
    

    优化查询,

    【讨论】:

      【解决方案3】:

      另一种适用于 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';
      

      【讨论】:

      【解决方案4】:

      这对我有用:

      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'); 
      

      【讨论】:

        【解决方案5】:
        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';
        

        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'); 
        

        【讨论】:

        • @0mesh 它用于 mysql .. 我怀疑是 sql 和 postgre sql
        • 对于较大的表,此答案中的第一个解决方案可能要快得多。
        • 最佳答案,尤其是第一个,因为它允许您按多个字段进行匹配。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-12-22
        • 2014-12-24
        • 2019-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多