我有以下架构:
create table Took(
sID integer,
oID integer,
grade integer);
INSERT INTO Took VALUES
(1, 1, 90),
(1, 2, 100),
(2, 1, 90),
(2, 3, 80),
(2, 4, 85)
;
我也有以下查询:
(select sid from took) except all (select sid from took where grade < 90);
并且这产生了预期的输出1,1,2
,因为在这种情况下等级值>≥90。但是,当我将all
子句删除到
select sid from took) except (select sid from took where grade < 90);
输出只是1
。我知道all
确定是否存在重复项,所以在这种情况下我希望输出为1,2
而不仅仅是1
。最近怎么回事?
答案 0 :(得分:3)
从PSQL文档中,单独使用EXCEPT时:
EXCEPT运算符计算左SELECT语句结果中的行集,但不计算右结果的结果。
但是,当ALL与EXCEPT一起使用时:
除非指定了ALL选项,否则EXCEPT的结果不包含任何重复的行。对于ALL,在左表中具有m个重复项且在右表中具有n个重复项的行将在结果集中出现max(m-n,0)次。
在您的示例中,左SELECT查询的结果将是所有行的sid。
test=# select sid from took;
sid
-----
1
1
2
2
2
(5 rows)
并且,右SELECT查询的结果将是最后两行,其等级<90。
test=# select sid from took where grade < 90;
sid
-----
2
2
(2 rows)
现在,仅使用EXCEPT:
运行查询test=# (select sid from took) except (select sid from took where grade < 90);
sid
-----
1
(1 row)
这里发生了什么,
这是你得到的结果的解释。
现在,使用EXCEPT ALL运行查询:
test=# (select sid from took) except all (select sid from took where grade < 90);
sid
-----
1
1
2
(3 rows)
在这种情况下,我们只是从SELECT SELECT查询结果中删除右SELECT查询的结果。
希望,这有帮助。