从左联接中删除行

时间:2019-01-04 10:04:51

标签: sql postgresql left-join sql-delete

我想加入两个表并从中删除。

表1:

|ID| DATA|

表2:

|ID | ID_TAB1|

查询如下:

delete from table2 
using table2 as t2 left join table1 as t1 
on t2.ID_TAB1=t1.ID 
where t1.DATA='xxx';

问题在于,存在第三张桌子:

table3:

|ID|ID_TAB2|

运行我的语句时,它不会说

  

在表table2上进行更新或删除违反了在表table3上的外键约束

我确定table3中没有数据与t1.DATA='xxx'连接到行,为什么会出现此错误?我的查询不正确吗?

2 个答案:

答案 0 :(得分:0)

您可能是说:

delete from table2 
 using table1
where  table2.ID_TAB1=table1.ID 
  and  table1.DATA='xxx';

它与您的查询有什么区别

  • 它不会重新引入table2的第二个独立实例。否则,查询将从table2中删除所有行。

  • 连接的left资格被滥用。左联接的要点是包括table2中没有对应的table1.id且缺少的table1列设置为NULL的行。但是条件t1.DATA='xxx'与此矛盾。

答案 1 :(得分:0)

此查询:

delete from table2 
using table2 as t2 left join table1 as t1 
on t2.ID_TAB1=t1.ID 
where t1.DATA='xxx';

实际上是从table2中删除所有行(如果where中没有匹配项,则不删除任何行。t2table2之间没有连接,因此本质上是交叉联接。

documentation中所述(深入):

  

除非希望设置自联接,否则不要在using_list中重复目标表。

大概是,删除所有行会导致第三个表出现问题。请注意,您确实要删除的行也可能导致此问题。在这种情况下,您需要使用某种级联逻辑来处理错误。

您可以使用using子句并删除join来表达这一点:

delete from table2 t2
    using table1 t1 
    where t2.ID_TAB1 = t1.ID  and
          t1.DATA = 'xxx';

或者,只需在exists子句中使用where

delete from table2 t2
    where exists (select 1
                  from table1 t1
                  where t1.id = t2.id_tab1 and t1.data = 'xxx'
                 );