GROUP BY-内联视图和未联接的表

时间:2019-02-18 13:01:42

标签: sql oracle

我有以下ORACLE查询,试图在该查询中找到平均薪水最高的部门。我想在此实现中使用内联视图(即保留b数据集),但很难在WHERE和GROUP BY组件中找到合适的部分。我知道下面的GROUP BY和WHERE(不存在)是错误的。但是我该如何纠正呢?

select a.deptno from emp a, 
(select max(avg_sal) max_avg_sal from (select  
avg(sal) avg_sal from emp group by deptno) ) b 
group by a.deptno, b.max_avg_sal 
having avg(a.sal) = b.max_avg_sal

预期结果

deptno
10

Emp结构

deptno staff sal
10     A     1000
10     B     1500
11     C     1100
12     D     1000
12     E     900
12     F     1000

4 个答案:

答案 0 :(得分:0)

这是您想要的吗?

select e.*
from (select e.*, avg(e.salary) over (partition by e.deptno) as avg_salary
      from emp e
     ) e
order by avg_salary desc
fetch first 1 row only;

fetch first在Oracle 12c +中可用。您可以在早期版本中使用附加的子查询来做类似的事情。

答案 1 :(得分:0)

您可以使用子查询

select deptno from tablename
group by deptno
having avg(sal)= (select max(asal) from (select avg(sal) as asal from tablename group by deptdno)A)

答案 2 :(得分:0)

直接的方法是:

select deptno
from emp
group by deptno
order by avg(salary) desc
fetch first row with ties;

FETCH FIRST从Oracle 12c开始可用。

在Oracle 11g中,我们可以改用它:

select deptno
from
(
  select deptno, avg(salary) as avg_salary, max(avg(salary)) over () as max_avg_salary
  from emp
  group by deptno
)
where avg_salary = max_avg_salary;

但是您需要一个内联视图,即派生表(from子句中的子查询)的另一个词。看起来更笨拙。一个没有FETCH FIRST并且没有窗口函数的示例:

with d as
(
  select deptno, avg(salary) as avg_salary
  from emp
  group by deptno
)
, dmax as
(
  select max(avg_salary) as max_avg_salary
  from d
)
select d.*
from d
join dmax on dmax.max_avg_salary = d.avg_salary;

我觉得这很模糊,根本不建议这样做。当然,如果没有WITH子句,您也可以这样做。然后它的可读性甚至更低。

答案 3 :(得分:0)

我不知道为什么要这样写,但是如果您真的只想要内联视图而没有窗口子句,则可以这样写:

select b.deptno 
from   (SELECT deptno, avg(sal) avgsal from emp group by deptno ) b
cross join (SELECT max(avgsal) maxavgsal FROM (SELECT avg(sal) avgsal FROM emp group by deptno )) c
where  b.avgsal = c.maxavgsal;

如果您出于某些原因不喜欢CROSS JOIN,也是同样的事情:

select b.deptno 
from   (SELECT deptno, avg(sal) avgsal from emp group by deptno ) b
inner join ( SELECT max(avgsal) maxavgsal FROM 
   ( SELECT avg(sal) avgsal FROM emp group by deptno ) ) c
on b.avgsal = c.maxavgsal;