oracle 为什么where子句中不允许使用聚合函数

brccelvz  于 2022-11-03  发布在  Oracle
关注(0)|答案(4)|浏览(233)

我希望对此作出澄清。我在下面提出两个问题:
我们有一个雇员姓名表,其中包含ID、姓名和薪金列

1.  Select name from employee 
    where sum(salary) > 1000 ;

  2.  Select name from employee 
    where substring_index(name,' ',1) = 'nishant' ;

查询1不起作用,但查询2起作用。根据我的开发经验,我认为可能的解释是:
sum()作用于参数中指定的一组值。这里传递的是'salary'列,所以它必须将该列的所有值相加。但在where子句中,记录是逐个检查的,就像测试中检查第一条记录1一样。因此,sum(salary)不会被计算,因为它需要访问所有列的值,然后只返回一个值。
查询2的工作方式与substring_index()处理单个值相同,因此这里它处理提供给它的值。
你能证实我的理解吗?

6qftjkof

6qftjkof1#

不能在WHERE子句中使用SUM()的原因是子句的求值顺序。
FROM告诉您从哪里读取行。就在将行从磁盘读取到内存时,检查它们的X1 M3 N1 X条件。(实际上,在许多情况下,无法通过WHERE子句的行甚至不会从磁盘中读取。“条件”在形式上称为 * predicate *,某些 predicate 由查询执行引擎使用-以决定从基表中读取哪些行。这些被称为 access predicate 。)正如您所看到的,WHERE子句应用于呈现给引擎的每一行。
另一方面,只有在读取了所有行(用于验证所有 predicate )之后,才会进行聚合。
想想看:SUM()只适用于满足WHERE条件的行。如果将SUM()放在WHERE子句中,则要求循环逻辑。新行是否通过WHERE子句?我怎么知道?如果它通过,则必须将其包含在SUM中,但如果不通过,它不应该包含在SUM中。那么,我如何计算SUM条件呢?

nfg76nw0

nfg76nw02#

为什么不能在where子句中使用聚合函数
聚合函数作用于数据集。WHERE子句不能访问整个数据集,而只能访问当前正在处理的行。
你当然可以使用HAVING子句:

select name from employee 
group by name having sum(salary) > 1000;

如果必须使用WHERE,则可以使用子查询:

select name from (
    select name, sum(salary) total_salary from employee
    group by name
) t where total_salary > 1000;
6ioyuze2

6ioyuze23#

sum()是一个聚合函数。通常,您会希望它与group by一起使用。因此,您的第一个查询缺少group by。在group by查询中,having用于在聚合 * 之后 * 进行筛选:

Select name
from employee 
group by name
having sum(salary) > 1000 ;
rmbxnbpk

rmbxnbpk4#

使用having可以正常工作,因为查询直接指向该列中的行,而where则会失败,因为只要不满足条件,查询就会不断地来回循环。

相关问题