对重复值进行平均操作

时间:2014-07-29 06:32:42

标签: sql select

我有两张桌子,员工和认证。

认证表包含经认证可驾驶飞机的员工名单。一名员工可能获得许多飞机的认证,反之亦然。并非所有员工都获得认证。

每位员工都会领薪水。 只有一个薪水,无论多少个证书。

如何找到至少获得一架飞机认证的员工的平均工资?

我的问题是,

SELECT AVG(SALARY) FROM EMPLOYEE E, CERTIFIED C WHERE E.EID=C.EID;

如果员工获得两架飞机的认证,则包括两次工资。所以AVG(薪水)给出了错误的价值。

我是新手,所以如果我的问题看起来太基本,我很抱歉。帮助

2 个答案:

答案 0 :(得分:1)

你想在这里进行半连接。您可以使用IN谓词实现它:

SELECT AVG(SALARY)
FROM EMPLOYEE
WHERE EID IN (
             SELECT EID
             FROM CERTIFIED
             )
;

或使用EXISTS谓词:

SELECT AVG(e.SALARY)
FROM EMPLOYEE AS e
WHERE EXISTS (
             SELECT *
             FROM CERTIFIED AS c
             WHERE c.EID = e.EID
             )
;

如果CERTIFIED.EID可以为空并且确实有空值,IN谓词将不会按预期工作,尽管我认为将该证书存储在与任何员工无关的表中是不常见的。

或者您可以使用正确的连接(我建议您认真考虑切换到正确的连接语法),只需要加入一组 distinct EID值来自CERTIFIED,而不是直接来源CERTIFIED。对于派生表,您可以使用DISTINCT:

SELECT AVG(e.SALARY)
FROM EMPLOYEE AS e
INNER JOIN (
           SELECT DISTINCT EID
           FROM CERTIFIED
           ) AS c
    ON e.EID = c.EID
;

或GROUP BY:

SELECT AVG(e.SALARY)
FROM EMPLOYEE AS e
INNER JOIN (
           SELECT EID
           FROM CERTIFIED
           GROUP BY EID
           ) AS c
    ON e.EID = c.EID
;

答案 1 :(得分:-2)

如果员工只有一份工资,我建议

SELECT AVG(e.salary)
FROM employee e
WHERE e.id in (SELECT c.id FROM certified c)

这可以确保每次开斋一次。我仍然不明白认证表在这里做了什么。您是否只需要那些获得航班认证的员工工资?