我目前正在使用包含以下架构的数据库:
以下是我需要执行的任务:
对于任务1,我制定了以下查询(包含avg(薪水)用于测试目的):
select dname, count(*), avg(salary)
from department, employee
where dno = dnumber
group by dname having avg(salary)>30000;
给出输出:
DNAME COUNT(*) AVG(SALARY)
------------------------- ---------- -----------
Hardware 10 63450
Research 4 33250
Headquarters 1 55000
Administration 3 31000
Software 8 60000
Sales 14 40821.4286
然而,我无法弄清楚任务二。 **我需要具有相同的值,但仅限于男性的数量,但与上一个查询的平均值相同**。我尝试了以下声明:
select dname, count(*), avg(salary)
from department, employee
where dno = dnumber and (dno,sex) in (select dno, sex from employee where sex = 'M' )
group by dname having avg(salary)>30000;
这导致了正确的计数值,但导致了男性的部门平均工资,而不是男性和女性。如下所示:
DNAME COUNT(*) AVG(SALARY)
------------------------- ---------- -----------
Hardware 7 65785.7143
Research 3 36000
Headquarters 1 55000
Software 7 57285.7143
Sales 10 42150
请注意我必须使用嵌套查询,而不是CASE。
希望这是有道理的,任何帮助都会受到赞赏。
感谢。
答案 0 :(得分:2)
您可以使用CASE
进行男性员工人数统计还将显式连接(FROM CLAUSE中的逗号分隔表)转换为隐式连接
select D.dname, count(case when E.sex='M' then 1 else 0), avg(E.salary)
from department D
join employee E
on E.dno = D.dnumber
group by D.dname
having avg(Esalary)>30000;
根据OP注释,如果需要仅使用嵌套查询来完成,则可以使用子查询来完成
select T.dname, count(*), T.salary as AverageSalary
FROM employee E
join ( select D.dname, D.dnumber, avg(salary) as salary
from employee E
join department D
on E.dno = D.dnumber
group by D.dname, D.dnumber
having avg(salary) > 30000 ) T
on E.sex ='M'
and E.dno = T.dnumber
group by T.dname, T.salary
答案 1 :(得分:1)
这也可以通过在将子查询,派生表或每个部门的cte应用于过滤员工之前评估总体平均值来完成。另请注意,加入join
的偏好不在where
。
with cteSalary as
(
select dname, dno, avg(salary) as avgSalary
from department inner join employee on dno = dnumber
group by dname, dno
)
select s.dname, count(e.fname), s.avgSalary
from employee e inner join cteSalary s on e.dno = s.dno
where e.sex = 'M' and s.avgSalary > 30000
group by s.dname, s.avgSalary;
答案 2 :(得分:0)
另一个解决方案是这个(未经测试):
with t as
(select dname, sex,
count(*) over (partition by dno, sex) as count_emp,
avg(salary) over (partition by dno) as avg_salary
from department
join employee on dno = dnumber)
select distinct *
from t
where avg_salary > 30000
and sex = 'M';