1

I have TableA that can have many TableB related to it and TableB can have many TableC rows related to it which TableC has many TableD rows. So TableA -> TableB -> TableC -> TableD. What I want to do is given the TableA row id, select all the TableD rows that are related through other tables and delete all of them.

TableA   |   TableB |   TableC |   TableD
--------------------------------------
tableAId | tableAId | tableBId | tableCId

         | tableBId | tableCId | tableDId

and the query i've tried:

DELETE FROM TableD
 WHERE TableA.tableAId = 2
 AND TableA.tableAId= TableB.tableAId
 AND TableB.tableBId= TableC.tableBId
 AND TableC.tableCId = TableD.tableCId 

sample table

TableA        TableB                     TableC                TableD

tableAID | tableAID  tableBId | tableBId   tableCId | tableCId   tableDId
---------|--------------------|---------------------|---------------------
 1       | 1            15    |  15         5       | 6              4
 2       | 2           16     |  16         6       | 5              3
                                                      5              14
                                                      5              11   

Desired result, Given tableAId = 1

TableA        TableB                     TableC                TableD

tableAID | tableAID  tableBId | tableBId   tableCId | tableCId   tableDId
---------|--------------------|---------------------|---------------------
 1       | 1            15    |  15         5       | 6              4
 2       | 2           16     |  16         6       |
3
  • 1
    Sample data and desired results would really help. Commented Sep 11, 2018 at 18:28
  • added sample and desired results, hope it makes sense Commented Sep 11, 2018 at 18:38
  • Your query almost done. Just add to it the list of using tables: DELETE FROM TableD USING TableA, TableB, TableC WHERE ... More about USING clause in the documentation: postgresql.org/docs/current/static/sql-delete.html Commented Sep 11, 2018 at 19:40

2 Answers 2

1

Use the following subquery to get all tableCIds that are related to your given tableAId:

SELECT DISTINCT TableC.tableCId
FROM TableC
LEFT JOIN TableB ON TableC.tableBId = TableB.tableBId
WHERE TableB.tableAId = 2

You can now use this subquery in your delete command, which should work somehow like this:

DELETE FROM tableD
USING ( ... ) sub
WHERE tableD.tableCId IN (SELECT * FROM sub)
Sign up to request clarification or add additional context in comments.

Comments

0

Something like this,

DELETE
FROM TableD AS inner
WHERE EXISTS (
  SELECT
  FROM tableD AS outer
  JOIN tableC
    USING (tableDid)
  JOIN tableB
    USING (tableBid)
  JOIN tableA
    USING (tableAid)
  WHERE tableAId = 2
   AND outer.tableDid = inner.tableDid
);

2 Comments

That worked, just had to change the inner and outer names and where you had USING (tableDid) shoulda be USING (tableCid)
Don't you need to quote "outer" as it is a reserved keyword?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.