【问题标题】:postgres delete from indirectly related tablespostgres 从间接相关的表中删除
【发布时间】:2019-02-16 07:42:04
【问题描述】:

我有一个 TableA 可以有很多与之相关的 TableB,而 TableB 可以有很多与之相关的 TableC 行,而 TableC 有很多 TableD 行。所以表A->表B->表C->表D。我要做的是给定 TableA 行 id,选择所有通过其他表相关的 TableD 行并将它们全部删除。

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

         | tableBId | tableCId | tableDId

以及我尝试过的查询:

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

样本表

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   

想要的结果,给定 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       |

【问题讨论】:

  • 样本数据和期望的结果真的很有帮助。
  • 添加了样本和期望的结果,希望有意义
  • 您的查询即将完成。只需将使用表的列表添加到其中:DELETE FROM TableD USING TableA, TableB, TableC WHERE ... 更多关于文档中的USING 子句:postgresql.org/docs/current/static/sql-delete.html

标签: sql postgresql


【解决方案1】:

使用以下子查询获取与给定tableAId相关的所有tableCIds:

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

你现在可以在你的删除命令中使用这个子查询,它应该像这样工作:

DELETE FROM tableD
USING ( ... ) sub
WHERE tableD.tableCId IN (SELECT * FROM sub)

【讨论】:

    【解决方案2】:

    类似的,

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

    【讨论】:

    • 那行得通,只需要更改内部和外部名称以及 USING (tableDid) 的位置应该是 USING (tableCid)
    • 您不需要引用"outer",因为它是保留关键字吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多