ChatGPT解决这个技术问题 Extra ChatGPT

ORA-00979 不是按表达式分组

我通过以下查询得到 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 子句的示例。我尝试一次从组中删除每个字段,但仍然遇到相同的错误。


A
Aaron Digulla

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

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

FOO BAR
0   A
0   B

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


不,您不需要将它们放在您的 order by 子句中
我尝试将 ORDER BY 中的两列添加到 GROUP BY。那行得通。谢谢!
或者换一种说法:如果您有两列并按第一列分组,这意味着您将在每个结果行的第二列中获得多个值。由于只有一个结果行但有许多值可供选择,数据库应该返回哪一个?它偶然发现的第一个?
@AaronDigulla 这就是 MySQL 所做的,世界并没有结束:p
我部分同意。但假设以下情况:有 4 列:A、B、C 和 D。现在我将 (A,B,C) 设置为复合键。那么“select A,B,max(C), D ... group by A, B”是没有歧义的,因为对于 A,B 和 C 的每个组合,D 已经定义。甲骨文仍然拒绝履行其职责。
R
Ram Sharma

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


P
Peter O.

太糟糕了,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);

@GlennFromIowa 鉴于我的伪表在上面没有严格定义,而且我不再为 11g 的公司工作,我无法提供更好的例子,尽管我上次测试它时这是一个问题。
只是出于好奇,您何时想要随机结果的示例是什么?我想不出任何你想按 FOO 分组并获得 BAR 随机行的原因。
B
BobRodes

如果您通过包含 GROUP BY 子句进行分组,则 SELECT 中的任何表达式,它不是组函数(或聚合函数或聚合列),例如 COUNTAVGMINMAX , 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 子句中删除组(聚合)函数。


P
Pavel Zimogorov

您应该执行以下操作:

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;

V
Vijay

当 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) .

3
3pitt

除了其他答案之外,如果 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

c
cнŝdk

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,它会给出同样的错误。


i
ieselisra

“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));

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅