为什么“ANY”无法正常工作?
我正在学习使用Oracle 10g的SQL。我需要一个查询来返回员工最多的部门在更新句子中使用它。我已经解决了,但我无法弄清楚,为什么这个查询将无法工作:为什么“ANY”无法正常工作?
select deptno
from (select deptno,
count(*) num
from emp
group by deptno)
where not num < any(select count(deptno)
from emp
group by deptno)
这让我为难,根据它应该是相当于和优化成以下的文档更因为:
select deptno
from (select deptno,
count(*) num
from emp
group by deptno)
where not exists(select deptno,
count(*)
from emp
having count(*) > num
group by deptno)
那个工作没有错误。以下也有效:
select deptno
from (select deptno,
count(*) num
from emp
group by deptno)
where num = (select max(alias)
from (select count(deptno) alias
from emp
group by deptno))
select deptno
from emp
group by deptno
having not count(deptno) < any(select count(deptno)
from emp
group by deptno)
编辑。如果我发布内部选择的返回值,可能会有所帮助。
的第一选择回报:
Dept. Number Employees
30 6
20 5
10 3
最后一个返回(3,5,6)
我单独检查他们。同样奇怪的是,如果我手动设置这些值,它将按预期工作,并将返回30作为拥有大部分员工的部门。
select deptno
from (select deptno,
count(*) num
from emp
group by deptno)
where not num < any(6,5,3)
我使用Oracle 10g 10.2.0.1.0
最后编辑,大概。仍然不知道发生了什么,但行为就好像最后一个select以某种方式返回null。所以,即使我删除了'不',它仍然不会选择任何东西。
如果有人有兴趣,我也发现这个有用: TSQL - SOME | ANY why are they same with different names? 阅读第一个答案。最好避免使用任何/某些,全部。
校正(更新)
not num < any(select ...)
应该是相同的其他查询。你也可以尝试这个变化:
num >= ALL(select ...)
但我不明白你为什么给出错误的结果。也许是因为not
的优先顺序。你可以trythis代替?:
not (num < ANY(select ...))
完整查询:
select deptno
from (select deptno, count(*) num from emp group by deptno)
where num >= all(select count(deptno) from emp group by deptno)
和:
select deptno
from (select deptno, count(*) num from emp group by deptno)
where not (num < any(select count(deptno) from emp group by deptno))
这里有一个类似的例子可以澄清的东西(标准SQL,可以很容易地转化为Oracle):
WITH T
AS
(
SELECT *
FROM (
VALUES (0),
(1),
(2),
(NULL)
) AS T (c)
)
SELECT DISTINCT c
FROM T
WHERE 1 > ALL (SELECT c FROM T T2);
这将返回空集合,这是合理的:给定表中存在空值,1 > NULL
为UNKNOWN,因此不知道值1是否大于集合中的所有值。
然而,加入NOT
操作:
WHERE NOT 1 > ALL (SELECT c FROM T T2);
返回所有值的集合,包括空值。乍一看这似乎是错误的:鉴于1 > 2
是假的,我们可以肯定地说,值1不大于集合中的所有值,而不管空值。
但是,在这种情况下,NOT仅仅是翻转早先的结果,即所有没有行的相反都是行! )
使用柱(而不是字面值为1)进一步考虑取反比较:
WHERE NOT c > ALL (SELECT c FROM T T2);
这一次它返回除了空值的所有行。
嘿,这真的很好知道,永远不会跨过我的脑海。但是我没有空值。 (我编辑澄清这一点)奇怪的是,如果我手动替换最后选择的值返回它会起作用,它甚至比我如果省略“NOT”,更改操作符'>'或'
我想我终于得到了最后一个。如果第一个表达式为空,则所有结果都为空,既不是真或假,如果它是一个值,它将不能与全部结果进行比较并返回false。 这让我觉得'num'被视为null,但只有当我使用第二个选择而不是值。 :S(感谢另一个奇怪的情况!) –
我怀疑他们的意思是'num不是 onedaywhen
我不知道我是否得到最后一部分,但编辑更清晰。另外,_some_和_any_应该是同一个运算符,而'num> = any(select ...)'将会返回所有的行,因为每一行至少等于它自己。 'num> = any(select ...)'对于5,6将是真实的,因为它们都将大于3. –
是的,你是对的。我在想'全部',写着'任何' –