DELETE Join

DELETE Join explained with practical SQL patterns, edge cases, and production-ready guidance.

5 min read · Last updated: March 2026 · Back to overview

Quick Answer

PostgreSQL does not support DELETE JOIN directly. Instead, use the USING clause to reference a second table: DELETE FROM table1 USING table2 WHERE table1.col = table2.col. For cross-database compatibility, use a subquery with WHERE col IN (SELECT ...).

Spin up a Postgres database in 20 seconds with Vela.

Try Vela Sandbox

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 USING over 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 RETURNING after the WHERE clause to capture the deleted rows for audit logging.
  • Test the join condition with a SELECT first to confirm it targets exactly the rows you intend to delete.
  • The USING clause performs an inner join — rows in the target table with no match in the second table are not deleted.

Reference: PostgreSQL documentation — DELETE.

Continue in Modifying Data: DELETE CASCADE.

Related in this section: INSERT · INSERT Multiple Rows · UPDATE

Frequently Asked Questions

Does PostgreSQL support DELETE JOIN like MySQL?

No. PostgreSQL does not have DELETE JOIN syntax. Use DELETE FROM ... USING ... WHERE ... instead, which achieves the same result. For standard SQL compatibility, use DELETE FROM ... WHERE col IN (SELECT ...).

What is the difference between DELETE USING and a subquery?

Both remove the same rows. USING is PostgreSQL-specific and often produces a better query plan. A subquery using WHERE col IN (...) is standard SQL and works across databases. For large joined datasets, USING is generally preferred in PostgreSQL.

Can I join more than two tables in a DELETE USING statement?

Yes. List additional tables in the USING clause separated by commas and add their join conditions to the WHERE clause.

Can I use RETURNING with DELETE USING?

Yes. Add RETURNING after the WHERE clause. You can reference columns from the target table in the RETURNING list, but not from the USING table.

What happens if no rows in the USING table match the condition?

No rows are deleted. The USING clause behaves like an inner join, so rows in the target table with no match in the USING table are left untouched.