2012-12-10 88 views
-1

我可以得到员工的数量和平均工资,但是当我尝试获得额外的选择时,选择列出支付的员工数量低于平均水平,则失败。如何获得薪水低于平均工资的所有员工?

select count(employee_id),avg(salary) 
from employees 
Where salary < avg(salary); 
+0

我想你需要一个HAVING子句而不是WHERE子句。 – ceejayoz

+3

请使用真正的英语句子,而不是您的标题最初组成的关键字散乱的列表。 – meagar

回答

3
select count(*), (select avg(salary) from employees) 
from employees 
where salary < (select avg(salary) from employees); 
1
select TotalNumberOfEmployees, 
      AverageSalary, 
      count(e.employee_id) NumberOfEmployeesBelowAverageSalary 
    from (
      select count(employee_id) TotalNumberOfEmployees, 
        avg(salary) AverageSalary 
       from employees 
     ) preagg 
left join employees e on e.salary < preagg.AverageSalary 
group by TotalNumberOfEmployees, 
      AverageSalary 

注:我使用了LEFT JOIN,所以如果你有3名相等的员工,它会显示0,而不是任何结果(以下低于平均一个人)。

+0

+1虽然我仍然试图解决这个问题是否有合理的方法来使用窗口函数;) – 2012-12-10 20:48:01

1

问题是AVG是一个聚合函数。 SQL不够聪明,无法弄清楚如何在行内混合聚合结果。传统的方式是使用连接:

select count(*), avg(e.salary), 
     sum(case when e.salary < const.AvgSalary then 1 else 0 end) as NumBelowAverage 
from employees e cross join 
    (select avg(salary) as AvgSalary from employees) as const 
+0

+1您也可以在此特例中使用交叉连接作为过滤器和简单计数(*)因为OP没有要求计算雇员总数。 – 2012-12-10 20:49:13

1

您不清楚在结果集中想要哪些列,这就很难回答您的问题。明确问题可以提高答案的质量。

你似乎想3个事实:

  1. 员工人数。
  2. 平均工资。
  3. 收入低于平均工资的员工人数。

你展现一个查询其确实为前两个事实工作:

SELECT COUNT(*) AS NumberOfEmployees, 
     AVG(Salary) AS AverageSalary 
    FROM Employees 

什么COUNT(*)COUNT(Employee_ID)之间的区别?不同之处在于后者只对Employee_ID列中存在非NULL值的行进行计数。一个好的优化器会认识到Employee_ID是一个主键并且不包含NULL值,查询也是一样的。但COUNT(*)更传统,对优化器的依赖性更低。

其他统计可以在选择列表中一个简单的值通过一个子查询生成:

SELECT COUNT(*) AS NumberOfEmployees, 
     AVG(Salary) AS AverageSalary, 
     (SELECT COUNT(*) 
      FROM Employees 
     WHERE Salary < (SELECT AVG(Salary) FROM Employees) 
     ) AS NumberOfEmployeesPaidSubAverageWages 
    FROM Employees 

在许多情况下,这是不恰当的写子查询那样,但是对于指定查询的解释,这很好。

+0

+1比我的方式更清晰 – 2012-12-11 06:11:52

0
select * from <table name> where salary < (select avg(<salary column name) from <table name>); 

例子:

select * from EMPLOYEE where sal < (select avg(emp_sal) from EMPLOYEE); 
+1

你应该详细说明你的答案。 –

0
SELECT e.ename,e.deptno,e.sal,d.avg 
FROM emp e,(SELECT deptno, avg(sal) avg 
      FROM emp 
      GROUP BY deptno) d 
WHERE e.deptno=d.deptno 
AND 
e.sal < d.avg 
+1

欢迎来到Stack Overflow!花点时间阅读帮助中心的[编辑帮助](// stackoverflow.com/editing-help)。堆栈溢出的格式与其他站点不同。 – FrankerZ

+2

此外,虽然此代码片段可能会解决问题,但[包括解释](// meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers)确实有助于提高帖子的质量。请记住,您将来会为读者回答问题,而这些人可能不知道您的代码建议的原因。也请尽量不要使用解释性注释来挤占代码,因为这会降低代码和解释的可读性! – FrankerZ

相关问题