ORA-00979不是依表达式分组


147

我正在使用以下查询获取ORA-00979:

SELECT cr.review_sk, cr.cs_sk, cr.full_name,
tolist(to_char(cf.fact_date, 'mm/dd/yyyy')) "appt",
cs.cs_id, cr.tracking_number
from review cr, cs, fact cf
where cr.cs_sk = cs.cs_sk
and UPPER(cs.cs_id) like '%' || UPPER(i_cs_id) || '%'
and row_delete_date_time is null
and cr.review_sk = cf.review_wk (+)
and cr.fact_type_code (+) = 183050
GROUP BY cr.review_sk, cr.cs_sk, cf.fact_date, cr.tracking_number
ORDER BY cs.cs_id, cr.full_name;

我找不到在同一查询中同时具有GROUP BY和ORDER BY子句的任何示例。我尝试一次从组中删除每个字段,但仍然遇到相同的错误。

Answers:


232

您必须将的所有列都SELECT放在GROUP BY或上,或在其上使用将结果压缩为单个值的函数(例如MINMAXSUM)。

一个简单的例子来了解为什么会发生这种情况:假设您有一个这样的数据库:

FOO BAR
0   A
0   B

然后你跑了SELECT * FROM table GROUP BY foo。这意味着数据库必须返回第一行的结果作为第一列0来满足,GROUP BY但是现在有两个值bar可供选择。您期望得到哪个结果- AB?还是数据库应该返回多个行,从而违反的约定GROUP BY


7
不,你不需要by子句将它们放在您的订单
Xaisoft

3
我尝试将ORDER BY中的两列添加到GROUP BY。那行得通。谢谢!
特里萨(Theresa)2009年

1
或换一种说法:如果您有两列,并按第一列分组,则意味着每个结果行的第二列中都有多个值。由于只有一个结果行,但有很多值可供选择,因此数据库应返回哪个值?第一次偶然发现?
亚伦·迪古拉

6
@AaronDigulla这就是MySQL所做的,世界并没有结束:p
Chris Baker

1
我部分同意。但是假设以下情况:有4列:A,B,C和D。现在,我将(A,B,C)设置为组合键。然后,“选择A,B,max(C),D ...由A,B分组”就不存在歧义,因为对于A,B和C的每种组合,都已经定义了D。甲骨文仍然拒绝履行职责。
ga

17

GROUP BY子句SELECT中包括不是组函数参数的所有表达式。


9

太糟糕了,Oracle具有这样的局限性。当然,不在GROUP BY中的列的结果将是随机的,但有时您希望这样做。愚蠢的Oracle,您可以在MySQL / MSSQL中执行此操作。

但是Oracle有一个解决方法:

虽然以下行不起作用

SELECT unique_id_col, COUNT(1) AS cnt FROM yourTable GROUP BY col_A;

您可以使用以下一些0来欺骗Oracle,以使您的列保持在范围内,而不是按其分组(假设这些是数字,否则使用CONCAT)

SELECT MAX(unique_id_col) AS unique_id_col, COUNT(1) AS cnt 
FROM yourTable GROUP BY col_A, (unique_id_col*0 + col_A);

上面没有严格定义@GlennFromIowa的伪表,而且我不再为11g的公司工作,我无法提供更好的示例,尽管上次测试时这是一个问题。
Joseph Lust 2015年

4
出于好奇,什么时候需要随机结果的例子是什么?我想不出您要按FOO分组并随机获得BAR的任何原因。
凯尔·布​​莱恩汀汀

4

如果借助于包括分组GROUP BY子句,在任何表达式SELECT,这是不组函数(或集合函数或聚集的列),例如COUNTAVGMINMAXSUM等(的集合函数列表)应存在于GROUP BY子句。

示例(正确的方式)(这里employee_id不是组函数(非聚合列),因此它必须出现在中GROUP BY。相反,sum(salary)是组函数(聚合列),因此不需要在GROUP BY子句中出现。

   SELECT employee_id, sum(salary) 
   FROM employees
   GROUP BY employee_id; 

示例(错误的方式)(这里employee_id不是组函数,它没有出现在GROUP BY子句中,这将导致ORA-00979错误。

   SELECT employee_id, sum(salary) 
   FROM employees;

要纠正你需要做一个如下:

  • SELECT子句中 列出的所有非聚合表达式包括在内GROUP BY子句中
  • SELECT子句中删除组(聚合)函数。

2

您应该执行以下操作:

SELECT cr.review_sk, 
       cr.cs_sk, 
       cr.full_name,
       tolist(to_char(cf.fact_date, 'mm/dd/yyyy')) "appt",
       cs.cs_id, 
       cr.tracking_number
from review cr, cs, fact cf
where cr.cs_sk = cs.cs_sk
       and UPPER(cs.cs_id) like '%' || UPPER(i_cs_id) || '%'
       and row_delete_date_time is null
       and cr.review_sk = cf.review_wk (+)
       and cr.fact_type_code (+) = 183050
GROUP BY cr.review_sk, cr.cs_sk, cf.fact_date, cr.tracking_number, cs.cs_id, cr.full_name
ORDER BY cs.cs_id, cr.full_name;

1

当 在选择表达式和按表达式分组的两个地方都未使用UPPERLOWER关键字时,也会出现相同的错误。

错误的:-

select a , count(*) from my_table group by UPPER(a) .

对 :-

select UPPER(a) , count(*) from my_table group by UPPER(a) .

1

group by用于聚合某些数据,具体取决于聚合函数,而不是需要将需要分组的一个或多个列放入的数据。

例如:

select d.deptno, max(e.sal) 
from emp e, dept d
where e.deptno = d.deptno
group by d.deptno;

这将导致部门最高工资。

现在,如果我们忽略d.deptnofrom group by子句,它将给出相同的错误。


1

除其他答案外,如果order by子句不一致,也可能导致此错误。例如:

select 
    substr(year_month, 1, 4)
    ,count(*) as tot
from
    schema.tbl
group by
    substr(year_month, 1, 4)
order by
    year_month
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.