我试图找到公司员工的薪水高于所有员工的平均薪水。我想从一开始就指出,我不希望平均薪水出现在最终结果中,因此我在SELECT语句中忽略了它。这些是我尝试过的事情:
SELECT employee.lastname,employee.firstname,employee.salary FROM employee
GROUP BY employee.salary
HAVING employee.salary > avg(employee.salary);
这将导致结果表为空
但是,尽管有'='符号,但以下内容令人惊讶地返回了公司的所有员工。
SELECT employee.lastname,employee.firstname,employee.salary FROM employee
GROUP BY employee.salary
HAVING employee.salary = avg(employee.salary);
这将再次返回空表:
SELECT employee.lastname,employee.firstname,employee.salary FROM employee
WHERE (SELECT avg(employee.salary) FROM employee
GROUP BY employee.salary
HAVING employee.salary > AVG(employee.salary));
因此,总结一下这篇文章,我将对正确使用HAVING和聚合函数有一些见解,并对摘要导致空表的原因有一些见解。
答案 0 :(得分:2)
当您GROUP BY employee.salary
时,每个组的平均薪水等于employee.salary
,因为该组的所有薪水均相等。
所以条件:
employee.salary > avg(employee.salary)
始终为FALSE
,并且您没有任何行,
和条件:
employee.salary = avg(employee.salary)
始终为TRUE
,结果是返回所有组。
得到您想要的正确代码是:
SELECT employee.lastname, employee.firstname, employee.salary
FROM employee
WHERE employee.salary > (SELECT avg(employee.salary) FROM employee);
答案 1 :(得分:1)
如果您将括号放错了位置而导致语法错误,请移去(
之前的起始左括号avg(..
和分号之前的最后一个封闭括号)
SELECT employee.lastname,
employee.firstname,employee.salary
FROM employee
WHERE employee.salary >
( SELECT avg(employee.salary) FROM
employee);
答案 2 :(得分:1)
尝试一下
SELECT lastname, firstname, salary
FROM employee
WHERE salary > (SELECT AVG(salary) FROM employee)
ORDER BY salary DESC
在GROUP BY
或SELECT
子句中仅使用聚合函数时,平均值子查询不需要HAVING
。
或者使用更精美的东西:
SELECT lastname, firstname, salary
FROM
(
SELECT lastname, firstname, salary
, AVG(salary) OVER () AS avg_salary
FROM employee
) q
WHERE salary > avg_salary
答案 3 :(得分:0)
您可以处理两个集合/表,一个记录级别,另一个集合,即使它们是同一集合:
select e.lastname , e.firstname , e.salary
FROM employee e, (
select avg(a.salary) avg_salary
from employee a
) av
where 1=1
and e.salary > av.avg_salary
;
答案 4 :(得分:0)
您已通过employee.salary
进行汇总。因此,在此查询中:
HAVING employee.salary > avg(employee.salary);
HAVING
之前的每一行都具有一个正确的salary
值。一个值的平均值-无论组中有多少个-都是该值。由于值不能大于其自身,因此不会返回任何行。
此子句:
HAVING employee.salary = avg(employee.salary);
是完全一样的东西,除了所有薪水不为{NULL
的行都符合此条件。因此,将返回所有行。
正如其他人所提到的,更典型的解决方案是子查询:
select e.*
from employee e
where e.salary > (select avg(e2.salary) from employee e2);
请注意表别名的使用。强烈建议这些。
更现代的解决方案将使用窗口函数:
select . . . -- select the columns you want
from (select e.*, avg(e.salary) over () as avg_salary
from employee e
) e
where e.salary > avg_salary;