MySQL:两个结果集的差异

47

如何获取两个结果集的差集?

假设我有两个结果集(每个结果集中只有一列):

result1:
'a'
'b'
'c'

result2:
'b'
'c'

我想用result1减去result2:result1 - result2,使它等于:

 difference of result1 - result2:
 'a'
3个回答

68

要执行result1 - result2,您可以将result1与result2连接起来,并仅输出存在于result1中的项。例如:

SELECT DISTINCT result1.column
FROM result1 LEFT JOIN result2 ON result1.column = result2.column
WHERE result2.column IS NULL

从集合论的角度来看,这是result1和result2之间的一个差集,即result1中存在但result2中不存在的元素。

如果你想要一个对称差分(即result1或result2中的元素,但不是两边都有的),你可以执行一个FULL OUTER JOIN,并过滤掉任一侧为NULL的元素。

最后,需要注意的是,如果你的数据库中有可为空的列,那么这种方法可能效果不佳,因为空值将被视为连接失败的行的相同部分。幸运的是,连接通常在具有索引的列上执行,可空值很少出现。

另请参阅:相关博客文章的网络归档版本


感谢您的澄清,我已经有一段时间没有使用MySQL了。 - Francisco Soto
1
这实际上是一个“集合差”,而你所说的只是“对称差”,可以通过FULL OUTER JOIN来实现:https://dev59.com/Ym445IYBdhLWcg3wkLJG - n0099
感谢提供正确的术语!我会进行更新。 - rjh

17
如果你希望得到result1中不在result2中的结果,可以考虑以下方法:
SELECT distinct result1
FROM t1 
WHERE result1 NOT IN (select distinct result2 from t2);

或者:
SELECT distinct result
from t1 t
where NOT EXISTS (select 1 from t2 where result2 = t.result1)

注意:如果result1result2的子集,则上述查询将返回一个空集(它们不会显示在result1中不存在的result2中的内容),因此它们不是集合差异,但也可能很有用(可能比外部连接更有效率)。


1
我最近有一个需求,需要找到两个结果集之间的差异。虽然上面的答案对我有所帮助,但我希望它们再详细一些。对于给定的问题,我发现了两种解释:
  1. 结果集可以来自2个不同的表
  2. 结果集来自同一张表
对于第一种情况,结果集可以来自两个不同的表,让我们以两个表为例:science_studentmath_student
科学生
enter image description here

math_student
在此输入图片描述


result1 - result2

result1: select student_id from science_student where id > 2

result2: select student_id from math_student

result1 - result2的差异是STUD3。

因此,查找差异的查询将是:

select result1.student_id 
 from 
 (select student_id from science_student where id > 2) result1
 left join
 (select student_id from math_student) result2
 on result1.student_id = result2.student_id 
 where result2.student_id is null;



对于第二种解释,结果集可以来自同一张表:

result1 - result2

result1: select student_id from science_student 

result2: select student_id from science_student where id > 2

result1和result2之间的差异是STUD1和STUD2。

相应的查询为:

select result1.student_id 
 from 
 (select student_id from science_student) result1
 left join
 (select student_id from science_student where id > 2) result2
 on result1.student_id = result2.student_id 
 where result2.student_id is null;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接