PostgreSQL does not have a DELETE JOIN statement like MySQL. Instead, it provides the USING clause, which lets you reference additional tables to determine which rows to delete. For portability across database systems, a subquery approach also works.
DELETE with USING clause
Syntax for deleting rows in one table based on matching rows in another:
DELETE FROM table1
USING table2
WHERE condition;
The join is expressed through the WHERE clause rather than an explicit JOIN keyword.
Example: remove all members whose phone numbers appear on a denylist:
DELETE FROM member
USING denylist
WHERE member.phone = denylist.phone;
Output:
DELETE 2
Two rows were removed from the member table. Verify the result:
SELECT * FROM member;
Output:
id | first_name | last_name | phone
----+------------+-----------+----------------
3 | Lily | Bush | (408)-124-9221
(1 row)
Only Lily Bush remains because her phone number was not on the denylist.
DELETE with a subquery
The USING clause is PostgreSQL-specific. For queries that must run on multiple database systems, use a subquery instead:
DELETE FROM member
WHERE phone IN (
SELECT phone
FROM denylist
);
The subquery returns the list of phones to match, and the outer DELETE removes every member row whose phone is in that list. Both approaches produce the same result.
Practical tips
- Prefer
USINGover a subquery when working exclusively in PostgreSQL — it tends to produce a more efficient query plan. - Use a subquery when you need the query to work on other databases (MySQL, SQLite) or your ORM generates standard SQL.
- Add
RETURNINGafter theWHEREclause to capture the deleted rows for audit logging. - Test the join condition with a
SELECTfirst to confirm it targets exactly the rows you intend to delete. - The
USINGclause performs an inner join — rows in the target table with no match in the second table are not deleted.
Reference: PostgreSQL documentation — DELETE.