为什么不应用此代码的group by子句?

时间:2016-04-23 12:42:20

标签: sql oracle select group-by

我按照我选择的语句分组,但几乎就像数据库甚至没有看到group by子句一样,因为它抛出一个错误并说emp_firstname不是单组组函数

select emp_firstname, emp_surname, sum(timesheet_hours), sum(payroll_standard*grade_rate), sum((payroll_overtime*grade_rate)*1.5), sum(sum(payroll_standard*grade_rate) + sum((payroll_overtime*grade_rate)*1.5)), sum(payroll_pension)
from funtom_employee
join funtom_payroll on emp_id = payroll_emp
join funtom_timesheet on timesheet_id = payroll_timesheet
join funtom_grade on emp_grade = grade_id
where payroll_date between '1-Apr-2014' and '31-Mar-2015'
group by emp_firstname, emp_surname

1 个答案:

答案 0 :(得分:1)

错误消息中出现混淆,因为Oracle支持嵌套聚合功能。换句话说,允许这种(非标准)语法:

SELECT AVG(MAX(salary))
FROM employees
GROUP BY department_id;

这样的嵌套函数相当于:

SELECT AVG(maxsalary)
FROM (SELECT MAX(salary) as maxsalary
      FROM employees
      GROUP BY department_id
     ) e

因此,sum()的嵌套本身并不是错误 - 尽管它会出现在其他数据库中。问题是您的查询混合了聚合级别。因此,引用键的奇怪错误消息,而不是聚合的列。

如评论中所述,您不需要嵌套聚合:

select emp_firstname, emp_surname, sum(timesheet_hours),
       sum(payroll_standard*grade_rate),
       sum((payroll_overtime*grade_rate)*1.5),
       (sum(payroll_standard*grade_rate) +   
        sum((payroll_overtime*grade_rate)*1.5)
       ),
       sum(payroll_pension)
from funtom_employee join
     funtom_payroll
     on emp_id = payroll_emp join
     funtom_timesheet
     on timesheet_id = payroll_timesheet join
     funtom_grade
     on emp_grade = grade_id
where payroll_date between '1-Apr-2014' and '31-Mar-2015'
group by emp_firstname, emp_surname;

也就是说,您的查询版本可能不正确。如果单个员工在任何表中都有多个或缺少行,则sum()可能会关闭。例如,我猜你会得到一张Cartesian产品用于时间表和工资单。

如果这是一个问题而您需要帮助,请询问其他问题,并提供示例数据和所需结果。

此外,学习使用表别名并限定列名。它有助于澄清列的来源。