为什么在where

时间:2017-02-26 16:10:08

标签: sql oracle aggregate-functions

我正在寻求对此的澄清。我在下面写两个问题:

我们有一个员工姓名表,其中包含列ID,姓名,工资

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

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

查询1不起作用,但查询2确实有效。根据我的开发经验,我觉得可能的解释是:

  

sum()适用于参数中指定的一组值。这里   '工资'列被传递,因此它必须添加此的所有值   柱。但是在where子句中,记录被逐一检查,   像第一个记录1一样检查测试,依此类推。从而   sum(salary)不会被计算,因为它需要访问所有列   值,然后只返回一个值。

查询2作为substring_index()工作于单个值,因此它在提供给它的值上工作。

请你验证我的理解。

4 个答案:

答案 0 :(得分:33)

您无法在SUM()子句中使用WHERE的原因是对子句的评估顺序。

FROM告诉您从哪里读取行。当从磁盘读取行到内存时,会检查它们是否为WHERE条件。 (实际上在很多情况下,WHERE子句失败的行甚至都不会从磁盘中读取。“条件”正式称为谓词,并且查询执行引擎使用了一些谓词 - 决定从基表中​​读取哪些行。这些行称为 access 谓词。)如您所见,WHERE子句在应用于引入引擎的每一行时应用。

另一方面,只有在读取了所有行(验证所有谓词)之后才进行聚合。

请注意:SUM()仅适用于满足WHERE条件的行。如果将SUM()放在WHERE子句中,则需要循环逻辑。新行是否通过WHERE子句?我怎么会知道?如果它会通过,那么我必须将其包含在SUM中,但如果没有,则不应包含在SUM中。那么我如何评估SUM条件?

答案 1 :(得分:8)

  

为什么我们可以在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;

答案 2 :(得分:4)

sum()是一个聚合函数。通常,您希望它与group by一起使用。因此,您的第一个查询缺少group by。在group by查询中,having用于在聚合后过滤

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

答案 3 :(得分:-1)

由于查询直接进入该列中的行而一直有效,而失败则是因为查询一直在条件不满足的情况下来回循环。