根据驾驶员状态显示薪水大于司机平均薪水的驾驶员

时间:2012-12-10 17:55:29

标签: sql oracle

我应该让司机的工资高于按其状态排序的所有司机的平均工资。使用我编写的代码,我无法通过子查询使用“Order by”功能。显示将是驱动程序名称,驱动程序状态和工资。这是我的代码

dr_status = the driver status
dr_drvname = driver name
dr_salary = driver salary
driver = driver table

select dr_drvname,dr_drvstatus,dr_salary
from driver
where dr_salary > (select avg(dr_salary) from driver group by dr_drvstatus)
group by dr_drvstatus;

4 个答案:

答案 0 :(得分:1)

我很确定你可以做这样的事情。

select dr_drvname,dr_drvstatus,dr_salary
from driver d1
where dr_salary > (
    select avg(dr_salary) from driver d2
    where d2.dr_drvstatus = d1.dr_drvstatus
)
group by dr_drvstatus;

答案 1 :(得分:1)

不使用OLAP函数并避免相关的子查询,我可能会写:

SELECT d.dr_drvname, d.dr_drvstatus, d.dr_salary
  FROM driver AS d
  JOIN (SELECT d2.dr_drvstatus, AVG(d2.dr_salary) AS avg_salary
          FROM driver AS d2
         GROUP BY d2.dr_drvstatus
       ) AS a ON d.dr_drvstatus = a.dr_drvstatus
 WHERE d.dr_salary < a.avg_salary;

子查询只会执行一次,以生成该状态的状态列表和平均工资。如果写为相关子查询(如answer jonhopkins中所述),则存在优化程序未发现子查询可转换为非相关子查询的风险

答案 2 :(得分:0)

当您使用像AVG()这样的聚合函数时,您几乎从不需要或希望该子查询具有“order by”或“group by”子句。它必须返回一个值才能用于比较...您想要单个值的顺序是什么?应该比较哪一个分组值?你选择让它变得疯狂。 ;-)

尝试删除该位并看到......将子选择切断为:

(select avg(dr_salary) from driver)

答案 3 :(得分:0)

我想你想要这样的东西?

select dr_drvname,dr_drvstatus,dr_salary, avg_sal
  from (select dr_drvname,dr_drvstatus,dr_salary, 
               avg(salary) over (partition by dr_drvstatus) avg_sal
          from driver)
 where dr_salary > avg_sal;