我正在寻求对此的澄清。我在下面写两个问题:
我们有一个员工姓名表,其中包含列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()工作于单个值,因此它在提供给它的值上工作。
请你验证我的理解。
答案 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)
由于查询直接进入该列中的行而一直有效,而失败则是因为查询一直在条件不满足的情况下来回循环。