试图理解sql查询中的“除了所有”

时间:2015-02-10 13:19:11

标签: sql intersect set-intersection set-difference set-operations

我遇到了这个例子,我不明白这意味着什么。

(SELECT drinker FROM Frequents)
     EXCEPT ALL
(SELECT drinker FROM Likes);
关系:频繁(饮酒者,酒吧),喜欢(饮酒者,啤酒)

在这种情况下ALL会做什么?结果与下面的查询有何不同?

(SELECT drinker FROM Frequents)
     EXCEPT
(SELECT drinker FROM Likes);

3 个答案:

答案 0 :(得分:6)

SQL EXCEPT运算符获取一个查询的不同行,并返回未出现在第二个结果集中的行。 EXCEPT ALL运算符不会删除重复项。出于行消除和重复删除的目的,EXCEPT运算符不区分NULL。

EXCEPT ALL返回第一个表中第二个表中不存在的所有记录,保留重复项。不幸的是,SQL Server不支持此运算符。

答案 1 :(得分:1)

我最近实施了 INTERSECT ALL EXCEPT ALL ,现在发现SO上没有多少资源。

考虑以下数据的示例。

您可以在sqlfiddle.com上重现示例,使用postgres 9.3 请注意,大多数流行的数据库不支持 INTERSECT ALL EXCEPT ALL 。使用row_number() over ()的解决方法当然是可行的。

create table x (V1 numeric);
create table y (V1 numeric);
insert into x values (1),(2),(2),(2),(3),(4),(4);
insert into y values (2),(3),(4),(4),(4),(5);

EXCEPT [ALL] 匹配两个表中的所有列,列类型和顺序必须匹配。

select * from x except select * from y;
| v1
----
|  1

select * from x except all select * from y;
| v1
----
| 1
| 2
| 2

EXCEPT sql处理不同的数据集,因此会自动删除任何重复项,只留下每行的单个副本。这导致在第二个数据集中仅基于匹配排除一行 另一方面, EXCEPT ALL 过程数据集考虑了重复的行数量。这导致返回表之间重复行的确切差异。准确地max(0, x.N - y.N)

另一个棘手的操作符,非常类似于 EXCEPT ALL INTERSECT ALL ,这个操作符返回每个匹配行的min(x.N, y.N)个重复项。

正如我提交的项目是开源的,我很高兴留下链接:github.com/Rdatatable/data.table。如果您要查找与之对比的工具,可能会很有用。 data.table是内存中的,主要是C实现的数据处理。它已经开源大约10年了。

答案 2 :(得分:1)

except运算符返回第一个表减去与第二个表的任何重叠。

设置A =(10,11,12,10,10)

设置B =(10,10)

A 除外 B->(11,12)

A 除所有 B->(10,11,12)

例外从集合A中删除所有出现的重复数据,而全部除外仅针对集合B中的每个出现从集合A中删除一次重复数据。