对缺失数据进行内部连接时的 SQL 删除

Posted

技术标签:

【中文标题】对缺失数据进行内部连接时的 SQL 删除【英文标题】:SQL Delete on inner join on MISSING data 【发布时间】:2014-05-01 21:25:54 【问题描述】:

我的问题与SQL DELETE with INNER JOIN 几乎相同;但我想在不相等时删除!

我的问题简介: 有2个表,bus_stops,bus_routes;

bus_routes id, bus_route_id,..other columns..
bus_stops id, bus_route_id,..other columns..

部分路线已被删除,但仍有公交车站,我也需要删除它们。意思是,我只需要删除没有关联公交路线的 bus_stops!

意思是这样的:

DELETE bs.* FROM bus_stops AS bs 
INNER JOIN bus_routes AS br 
ON bs.bus_route_id <> br.bus_route_id

但是上面的代码肯定不行。

【问题讨论】:

【参考方案1】:

你应该使用LEFT JOIN,下面的查询会起作用:

DELETE bs.*  
FROM bus_stops AS bs 
LEFT JOIN bus_routes AS br 
ON bs.bus_route_id = br.bus_route_id
WHERE br.bus_route_id IS NULL

【讨论】:

谢谢,Eduardo :) 解决方案非常简单,我错过了 :)【参考方案2】:

SQL 中的连接首先是两个表的笛卡尔积。这意味着表 A 的每条记录都与表 B 的每条记录相结合。然后,连接条件通过删除与条件不匹配的记录来减少记录。

如果您使用不等于 () 的 INNER JOIN,如果您至少有不同的值,则每条记录都将被删除。一个小例子:

Table A | B     Table C | D
=============   =============
        | 1             | 1
        | 2             | 2

A X B 的笛卡尔积是:

  | B | D
==========
  | 1 | 1
  | 1 | 2
  | 2 | 1
  | 2 | 2

如果您现在使用 B C 来选择值,结果将是:

  | B | D
==========
  | 1 | 2
  | 2 | 1

这将删除两条记录。

作为一种解决方案,尝试外部连接或子查询。

示例(子查询):

DELETE FROM C WHERE NOT EXISTS(SELECT * FROM A WHERE A.B = C.d)

示例(外部连接):

DELETE FROM C LEFT JOIN A ON C.D = A.B WHERE A.B IS NULL

【讨论】:

需要在LEFT JOIN后面加上ON子句

以上是关于对缺失数据进行内部连接时的 SQL 删除的主要内容,如果未能解决你的问题,请参考以下文章

winform,用c#链接 sql server。对数据库进行查询记录,增加记录,删除记录。,修改记录。

delphi中如何实现对sql数据库记录进行添加,删除,修改

机器学习数据预处理之缺失值:样本删除

使用SQL的更新语句时,一次可以对几个表进行更新?

请问TRUNCATE TABLE 与 DELETE在删除整个表的所有记录时的区别

多表联查时的sql删除语句的写法,即级联删除,将相关联的数据级联删除