如何改进此SQL代码?

时间:2014-03-14 07:45:40

标签: sql union

这是我的SQL问题。 我的SQL表“Employer”有3列:EmployerName,Salary,WorkPosition(例如Worker,Developer,Manager)。那么我怎样才能显示所有雇主的工资高于同一岗位工作人员的平均工资。

我这样做是为了获取每个位置的值并使用UNION显示所有这些值。 它起作用,但似乎不是一个好的解决方案。

(Select Employername 
From Employer
Where WorkingPosition = 'Worker' 
and Salary > (Select avg(Salary) from Employer
              Where WorkingPosition = 'Worker')) 
UNION
(Select Employername 
From Employer
Where WorkingPosition = 'Developer' 
and Salary > (Select avg(Salary) from Employer
              Where WorkingPosition = 'Developer')) 
UNION
(Select Employername 
From Employer
Where WorkingPosition = 'Manager' 
and Salary > (Select avg(Salary) from Employer
              Where WorkingPosition = 'Manager')) 

由于

4 个答案:

答案 0 :(得分:2)

您应该能够使用平均值加入派生表。

解决此类问题的最佳方法是将其分解为多个部分。第一部分是如何获得每个职位的平均工资。你应该GROUP能够得到这个:

SELECT AVG(Salary) AS AvgSalary, WorkingPosition
FROM Employer
GROUP BY WorkingPosition

然后你可以加入这个表 - 现在你让每个员工与他们职位的平均工资相关联:

SELECT *
FROM Employer
INNER JOIN
(
    SELECT AVG(Salary) AS AvgSalary, WorkingPosition
    FROM Employer
    GROUP BY WorkingPosition
) Averages ON Employer.WorkingPosition = Averages.WorkingPosition

最后,添加条件:

SELECT Employer.Employername
FROM Employer
INNER JOIN
(
    SELECT AVG(Salary) AS AvgSalary, WorkingPosition
    FROM Employer
    GROUP BY WorkingPosition
) Averages ON Employer.WorkingPosition = Averages.WorkingPosition
WHERE Employer.Salary > Averages.AvgSalary

如果您更习惯使用WHERE子句中的子查询,也可以这样做。我想两者都应该表现得相似:

SELECT Employername
FROM Employer
WHERE Salary > (SELECT AVG(Salary) 
                FROM Employer AS Averages 
                WHERE Employer.WorkingPosition = Averages.WorkingPosition)

答案 1 :(得分:2)

您没有说明您的DBMS,以下是ANSI SQL。

首先计算您感兴趣的所有工作位置的平均值。由于结果非常小,数据库服务器很可能会将其保留在内存中。因此,外部(最终)查询中的后续比较不需要每次重新计算平均值(当然这也取决于所使用的DBMS)

with avg_sales as (
  Select WorkingPosition, avg(Salary) as avg_salary
  from Employer
  Where WorkingPosition in ('Worker', 'Developer', 'Manager')
  group by WorkingPosition
)
Select emp.Employername 
From Employer emp
where Salary > (select avg_salary
                from avg_sales s
                where s.WorkingPosition = emp.WorkingPosition)
 and WorkingPosition in ('Worker', 'Developer', 'Manager');

答案 2 :(得分:1)

Select Employername From Employer
Where 
 ( WorkingPosition = 'Worker' and Salary > 
     (Select avg(Salary) from Employer Where WorkingPosition = 'Worker') 
 )
 or 
 ( WorkingPosition = 'Developer' and Salary > 
    (Select avg(Salary) from Employer Where WorkingPosition = 'Developer')
 ) 
 or
 ( WorkingPosition = 'Manager' and Salary > 
    (Select avg(Salary) from Employer Where WorkingPosition = 'Manager')
 ) 

或者

select o.employername 
  from employer o
where
  o.salary > (select avg(i.salary)
                from employer i
               where i.workingposition = o.workingposition
             )
     and
  o.workingposition in ('Worker', 'Developer', 'Manager')

答案 3 :(得分:1)

立即获取所有内容:

Select e1.Employername 
From Employer e1
Where 
e1.Salary > (Select avg(e2.Salary) from Employer e2
              Where e2.WorkingPosition = e1.WorkingPosition))