【问题标题】:ORA-00979 not a group by expressionORA-00979 不是按表达式分组
【发布时间】:2010-12-03 23:38:29
【问题描述】:

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

【问题讨论】:

    标签: sql oracle ora-00979


    【解决方案1】:

    您必须将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 都已经定义好了。甲骨文仍然拒绝做它的工作。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      太糟糕了,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 的随机行的任何理由。
      【解决方案4】:

      如果你通过包含GROUP BY子句进行分组,SELECT中的任何表达式,它不是组函数(或聚合函数或聚合列),例如COUNTAVGMINMAXSUM 等 (List of Aggregate functions) 应出现在 GROUP BY 子句中。

      示例(正确方式)(这里employee_id 不是组函数(非聚合列),所以它必须出现在GROUP BY 中。相比之下, sum(salary) 是一个组函数(聚合列),因此它不需要出现在GROUP BYclause 中。

         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 子句中删除组(聚合)函数。

      【讨论】:

        【解决方案5】:

        您应该执行以下操作:

        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;
        

        【讨论】:

          【解决方案6】:

          UPPERLOWER 关键字在 select 表达式和 group by 表达式中都没有使用时也会出现同样的错误。

          错误:-

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

          右:-

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

          【讨论】:

            【解决方案7】:

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

            【讨论】:

              【解决方案8】:

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

              【讨论】:

                猜你喜欢
                • 2011-05-25
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-06-04
                • 1970-01-01
                • 2021-05-27
                • 2013-03-29
                相关资源
                最近更新 更多