344
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'

i am getting the following error 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 ...

i tried giving

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

i tried giving

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

what is the problem with my query?

5
  • 3
    8.2? You should upgrade as soon as possible. That version is no longer supported. And please read the manual: there is no INNER JOIN available for the DELETE statement: postgresql.org/docs/8.2/static/sql-delete.html
    – user330315
    Commented Aug 1, 2012 at 6:53
  • any alternate method for executing this query without inner join
    – dude
    Commented Aug 1, 2012 at 6:55
  • See the manual, there is an example for exactly that.
    – user330315
    Commented Aug 1, 2012 at 6:59
  • 3
    @a_horse_with_no_name In the current 8.2 documentation it does not explicitly state that you cannot use a JOIN with DELETE. It suggests using their alternative non-standard USING syntax and otherwise suggests a WHERE but it does not mention anywhere that JOIN is not supported. Given that JOINs in DELETE clauses are allowed in MySQL and SQL Server, Postgres is the odd one out. Maybe they have their reasons, but they should be explicit postgresql.org/docs/8.2/sql-delete.html
    – icc97
    Commented Mar 10, 2021 at 7:00
  • 1
    8.2 is not the "current" documentation. A syntax diagram only documents the available option. Therefor any option not included in the syntax diagram is automatically not supported. The SQL standard does not include any option to "join" tables in a DELETE statement. So Postgres' USING option is just as non-standard as the JOIN option MySQL and SQL Server use. Neither of them defines the "standard" and e.g. Oracle and DB2 have not option at all to "join" other tables
    – user330315
    Commented Mar 10, 2021 at 7:13

7 Answers 7

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

or

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'); 
7
  • @0mesh its for mysql .. my doubt is for sql and postgre sql
    – dude
    Commented Aug 1, 2012 at 6:51
  • 36
    for larger tables, the first solution in this answer is potentially much faster. Commented Nov 2, 2014 at 16:58
  • 2
    The best answer, especially the first one, as it allows you to match by multiple fields.
    – Kostanos
    Commented Nov 14, 2017 at 14:58
  • the second one will work across all databases
    – icc97
    Commented Oct 7, 2022 at 8:05
  • What if you don't have a key column to use due to some temporary factor? If I know the rows I want to delete, from the result of a query, but don't necessarily have some specific identifier for them, how? Commented Jan 30, 2024 at 20:57
92

If you have more than one join you could use comma separated USING statements:

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

1
  • 2
    The a.id = b.id part is basically the join. I overlooked this, but it's the key piece, thank you! Commented Oct 6, 2022 at 13:47
69

This worked for me:

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'); 
1
  • 1
    Yes this is what postgres recommend as the 'standard' way to do it in the delete documentation notes: "A more standard way to do it is: DELETE FROM films WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo');". So the good thing of this is that this sql will work in other databases.
    – icc97
    Commented Oct 7, 2022 at 8:09
57

Another form that works with Postgres 9.1+ is combining a Common Table Expression with the USING statement for the join.

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';
1
33

Just use a subquery with INNER JOIN, LEFT JOIN or smth else:

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

to optimize the query,

12

Essentially everything mentioned here is mentioned in the docs, but no-one is specifying exactly what. So this is what the current (v15) DELETE docs says:

Notes

PostgreSQL lets you reference columns of other tables in the WHERE condition by specifying the other tables in the USING clause. For example, to delete all films produced by a given producer, one can do:

DELETE FROM films USING producers
 WHERE producer_id = producers.id AND producers.name = 'foo';

What is essentially happening here is a join between films and producers, with all successfully joined films rows being marked for deletion. This syntax is not standard. A more standard way to do it is:

DELETE FROM films
 WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo');

In some cases the join style is easier to write or faster to execute than the sub-select style.

1

By use of using , we can do that.

****

DELETE B.* 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'
------------------------------------------------------------------------

****

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.