我通过以下查询得到 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 子句的示例。我尝试一次从组中删除每个字段,但仍然遇到相同的错误。
您必须将 SELECT
的所有列放在 GROUP BY
中,或者在它们上使用将结果压缩为单个值的函数(如 MIN
、MAX
或 SUM
)。
一个简单的例子来理解为什么会发生这种情况:假设你有一个这样的数据库:
FOO BAR
0 A
0 B
然后运行 SELECT * FROM table GROUP BY foo
。这意味着数据库必须返回单行作为结果,第一列 0
来满足 GROUP BY
,但现在有两个 bar
值可供选择。您期望哪个结果 - A
或 B
?或者数据库应该返回多行,违反 GROUP BY
的约定?
在 GROUP BY
子句中包含不是组函数参数的所有 SELECT
表达式。
太糟糕了,Oracle 有这些限制。当然,不在 GROUP BY 中的列的结果将是随机的,但有时您想要这样。愚蠢的甲骨文,你可以在 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);
如果您通过包含 GROUP BY
子句进行分组,则 SELECT
中的任何表达式,它不是组函数(或聚合函数或聚合列),例如 COUNT
、AVG
、MIN
、MAX
, SUM
等 (List of Aggregate functions) 应出现在 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;
要更正,您需要执行以下操作之一:
在 GROUP BY 子句中包含 SELECT 子句中列出的所有非聚合表达式
从 SELECT 子句中删除组(聚合)函数。
您应该执行以下操作:
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;
当 UPPER 或 LOWER 关键字在 select expression 和 group by expression 中都没有使用时,也会出现同样的错误。
错误的 :-
select a , count(*) from my_table group by UPPER(a) .
正确的 :-
select UPPER(a) , count(*) from my_table group by UPPER(a) .
除了其他答案之外,如果 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
group by 用于聚合一些数据,具体取决于聚合函数,除此之外,您需要将需要分组的列或列放入其中。
例如:
select d.deptno, max(e.sal)
from emp e, dept d
where e.deptno = d.deptno
group by d.deptno;
这将导致部门的最高工资。
现在,如果我们从 group by 子句中省略 d.deptno
,它会给出同样的错误。
“Aaron Digulla”(此时的第一个)的答案启发了我使用 Spring Boot 2(JPA / Hibernate)和 CriteriaQuery / CriteriaBuilder 解决相同错误代码的方法。
制作一个选择列表,并将其添加到您的 criteriaQuery.multiselect()
List<Selection> selects = new ArrayList<>();
selects.add(seccionRoot.get("id"));
selects.add(synSeccionRoot.get("DDF"));
selects.add(synSeccionRoot.get("TTYU"));
selects.add(synSeccionRoot.get("4567"));
selects.add(seccionRoot.get("22").get("223"));
selects.add(tasaRoot.get("price"));
selects.add(tasaRoot.get("chair"));
cq.multiselect(selects.toArray(Selection[]::new));
然后您可以将 List 转换为 Expression[]
cq.groupBy(selects.toArray(Expression[]::new));