【问题标题】:Oracle "NOT A GROUP BY EXPRESSION ERROR-00979"甲骨文“不是按表达式 ERROR-00979 分组”
【发布时间】:2021-05-27 16:32:30
【问题描述】:

下面是我的 PL/SQL Oracle 代码。它会打印最多雇用员工的年份,并打印该年每月加入的员工数量。

如果我在没有 for 循环部分的情况下执行以下代码,则会产生错误:

不是按功能分组的错误。

我遗漏了一些明显的东西的原因是什么?

declare

      v_year  number(4);
      v_c     number(2);
begin
      select  to_char(hire_date,'yyyy') into v_year
      from  employees
      group by to_char(hire_date,'yyyy')
      having count(*) = 
             ( select  max( count(*))
               from  employees
               group by to_char(hire_date,'yyyy')); // gets the year where max employees joined
               
      dbms_output.put_line('Year : ' || v_year);

      for month in 1 .. 12
      loop
          select  count(*) into v_c
          from employees
          where  to_char(hire_date,'mm') = month and to_char(hire_date,'yyyy') = v_year;
          
          dbms_output.put_line('Month : ' || to_char(month) || ' Employees : ' || to_char(v_c));

     end loop;          

end;

下面是没有for循环的代码:

declare

      v_year  number(4);
      v_c     number(2);
begin
      select  to_char(hire_date,'yyyy') into v_year
      from  employees
      group by to_char(hire_date,'yyyy')
      having count(*) = 
             ( select  max( count(*))
               from  employees
               group by to_char(hire_date,'yyyy'));
               
      dbms_output.put_line('Year : ' || v_year);
end;

它会产生以下错误:

错误报告 - ORA-00979:不是 GROUP BY 表达式 ORA-06512:在第 6 行 00979. 00000 - “不是 GROUP BY 表达式”
*原因:
*行动:

【问题讨论】:

  • 请不要标记其他 RDBM - SQL Server != Oracle。
  • 对不起!更正。这是我第一次发布问题。
  • 您确定查询给出了该错误(查询似乎没有问题,除了多年返回的情况,那么将不可能在 SELECT 语句中使用 INTO 子句)?

标签: sql oracle plsql oracle11g


【解决方案1】:

您不需要为此使用 PL/SQL。此外,如果查询返回多于一行,则您的 SELECT ... INTO 将失败,如果两年或更长时间雇用的最大员工人数相同,则会失败。

select to_char(hire_date, 'YYYY'), to_char(hire_date, 'MM'), count(*)
from employees
group by rollup(to_char(hire_date, 'YYYY'), to_char(hire_date, 'MM'))
having to_char(hire_date, 'YYYY') =
    (select to_char(hire_date, 'YYYY')
       from employees
      group by to_char(hire_date, 'YYYY')
      having count(*) =
         (select max(count(*))
            from employees
           group by to_char(hire_date, 'YYYY')))
order by to_char(hire_date, 'YYYY'), to_char(hire_date, 'MM')

附:当我在 SQL Developer 中运行您的第二个示例(无循环)时,我遇到了与您相同的错误,但是当我在 SQL*Plus 中运行它时,我没有收到错误。 SQL*Plus 仅报告“PL/SQL 过程已成功完成”。

【讨论】:

  • 谢谢,戴尔。我在格式化帖子所需的 HTML 方面遇到了很多麻烦。
【解决方案2】:

我认为你最好使用并发循环重写代码,外部使用年份,内部使用月份,通过使用数组,例如

DECLARE
  v_year  OWA.nc_arr;
  v_month OWA.nc_arr;
  y       INT := 0;
  m       INT := 0;    
BEGIN
  FOR yr IN
    (
      SELECT hire_year
        FROM( SELECT TO_CHAR(hire_date, 'yyyy') AS hire_year, 
                     DENSE_RANK() OVER (ORDER BY COUNT(*) DESC) AS dr
                FROM employees
               GROUP BY TO_CHAR(hire_date, 'yyyy'))
       WHERE dr = 1
    )
  LOOP
    y := y + 1;
    v_year(y) := yr.hire_year;
    DBMS_OUTPUT.PUT_LINE('Year'||y||' : ' || v_year(y));

      FOR m IN 1 .. 12
      LOOP
          SELECT COUNT(*)
            INTO v_month(m)
            FROM employees
           WHERE TO_NUMBER(TO_CHAR(hire_date, 'yyyy'))=v_year(y)
             AND TO_NUMBER(TO_CHAR(hire_date, 'mm'))= m;
          
          DBMS_OUTPUT.PUT_LINE('Month : ' || m || ' Employees : ' || to_char(v_month(m)));
     END LOOP; 
  END LOOP;  
END;
/

其中分析函数用于年循环,因为可能超过一年,并且每年的月循环需要多个 (12) 变量。

【讨论】:

    猜你喜欢
    • 2011-05-25
    • 2010-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多