SQL - 如何获得每个部门的平均员工薪水?

时间:2016-09-26 17:48:34

标签: mysql sql oracle-sqldeveloper

这是表格的UML:https://dev.mysql.com/doc/employee/en/sakila-structure.html

enter image description here

这是我的尝试:

SELECT
    CONCAT(employees.first_name, ' ', employees.last_name) AS 'EmployeeName',
    salaries.emp_no AS 'Employee Number',
    departments.dept_no AS 'Department Number',
    departments.dept_name AS 'Department name',
    AVG(salaries.salary) AS 'Average salary'
FROM salaries
INNER JOIN dept_emp
    ON salaries.emp_no = dept_emp.emp_no
INNER JOIN employees
    ON salaries.emp_no = employees.emp_no
INNER JOIN departments
    ON dept_emp.dept_no = departments.dept_no
GROUP BY    salaries.emp_no,
            dept_emp.dept_no

我只是得到一个人工作的所有部门的平均员工薪水。 我希望的结果必须由每个部门的每个员工分组。任何帮助表示赞赏。

6 个答案:

答案 0 :(得分:1)

您可以尝试此查询

SELECT
    CONCAT(employees.first_name, ' ', employees.last_name) AS 'EmployeeName',
    salaries.emp_no AS 'Employee Number',
    departments.dept_no AS 'Department Number',
    departments.dept_name AS 'Department name',
    Cte_DepartmentSalaries.AvgSalary AS 'Average Salary'

--AVG(salaries.salary) AS 'Average salary'

FROM salaries
INNER JOIN dept_emp
    ON salaries.emp_no = dept_emp.emp_no
INNER JOIN employees
    ON salaries.emp_no = employees.emp_no
INNER JOIN departments
    ON dept_emp.dept_no = departments.dept_no   
LEFT JOIN (SELECT
    departments.dept_no,
    departments.dept_name,
    AVG(Salaries.Salary) AS AvgSalary
FROM Salaries
INNER JOIN dept_emp
    ON salaries.emp_no = dept_emp.emp_no
INNER JOIN departments
    ON dept_emp.dept_no = departments.dept_no
GROUP BY    departments.dept_no,
            departments.dept_name) AS Cte_DepartmentSalaries
    ON dept_emp.dept_no = Cte_DepartmentSalaries.dept_no

答案 1 :(得分:1)

如果您加入到之间和之间to_date的工资,您将获得这些时间段内工资的任何变化。

SELECT  CONCAT(e.first_name,' ',e.last_name) AS 'EmployeeName',
        s.emp_no AS 'Employee Number',
        d.dept_no AS 'Department Number',
        d.dept_name AS 'Department name',
        AVG(s.salaries.salary) AS 'Average salary'
FROM    employees e
        JOIN dept_emp de ON e.emp_no = de.emp_no
        JOIN salaries s ON s.emp_no = de.emp_no
                           AND (de.to_date >= s.from_date AND de.to_date <= s.to_date)
        JOIN departments d ON d.dept_no = de.dept_no
GROUP BY s.emp_no,
        d.dept_no

答案 2 :(得分:0)

将您的论坛更改为

GROUP BY employees.first_name, employees.last_name,  
         salaries.emp_no, departments.dept_no, departments.dept_name

mysql让你(以一种非常有用的方式恕我直言)不把所有列都用在组中。与其他平台不同,如果它们不在聚合函数中,则强制您将它们全部放入。所以你得到的不止一行,但你无法分辨,因为mysql为你搜索它们。

你可能还需要加入

INNER JOIN dept_emp ON salaries.emp_no = dept_emp.emp_no
  AND salaries.from_date = dept_emp.from_date 
  AND salaries.to_date = dept_emp.to_date 

答案 3 :(得分:0)

要查找表中的平均工资,请使用此mySQL查询。

[...]
shift $((OPTIND-1))
unset OPTIND
[...]

答案 4 :(得分:0)

从员工中选择AVG(工资) GROUP BY(departments_id);

答案 5 :(得分:-1)

看起来您需要检查员工薪资历史记录(from_date表)的to_datesalaries以及员工部门历史记录({{1} } table)。

假设dept_emp值为NULL表示&#34;当前&#34;,为了找到重叠,连接将是这样的:

to_date

就获得平均工资而言,这将会更加复杂,具体取决于你如何定义&#34;平均值&#34;。

例如,如果一名员工在一个部门工作,而一年年薪为20,000,那么四年年薪为30,000 ......平均工资报告为25,000(两个不同值的平均值),或者是28,000(所有年份的总薪水除以年数。)

要获得后一个结果,我们可以使用一个表达式来计算工资在部门中有效的天数......

 FROM salaries s 
 JOIN dept_emp de
   ON ( de.emp_no    = s.emp_no )
  AND ( de.from_date <= s.to_date   OR s.to_date  IS NULL )  
  AND ( de.to_date   >= s.from_date OR de.to_date IS NULL ) 

我们可以通过有效工资加倍,将所有这些加在一起,然后除以总天数:

     TIMESTAMPDIFF(DAY
       ,GREATEST(de.from_date,s.from_date)
       ,LEAST(IFNULL(de.to_date,DATE(NOW())),IFNULL(s.to_date,DATE(NOW())))
     )

表达式如下:

SUM(days*salary)/SUM(days)