ORA-00979 не группа по выражению - PullRequest
127 голосов
/ 05 октября 2009

Я получаю 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 в одном запросе. Я пытался удалить каждое поле из группы по одному, но все равно получаю ту же ошибку.

Ответы [ 8 ]

208 голосов
/ 05 октября 2009

Вы должны поместить все столбцы 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?

15 голосов
/ 05 октября 2009

Включить в предложение GROUP BY все выражения SELECT, которые не являются аргументами групповой функции.

8 голосов
/ 26 апреля 2011

Жаль, что у Oracle есть ограничения, подобные этим. Конечно, результат для столбца, не входящего в GROUP BY, будет случайным, но иногда вы этого хотите. Глупый Oracle, вы можете сделать это в MySQL / MSSQL.

НО есть обходной путь для Oracle:

Пока не работает следующая строка

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

Вы можете обмануть 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);
2 голосов
/ 19 апреля 2016

Вы должны сделать следующее:

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 голос
/ 11 февраля 2019

В дополнение к другим ответам, эта ошибка может произойти, если есть несоответствие в предложении 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
1 голос
/ 11 июля 2017

Если вы выполняете поиск в силу включения предложения GROUP BY, любое выражение в SELECT, которое не является групповой функцией (или статистической функцией или агрегированным столбцом), такое как COUNT, AVG, MIN, MAX, SUM и т. Д. ( Список агрегатных функций ) должен присутствовать в предложении 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.
1 голос
/ 07 апреля 2016

Группировка по используется для агрегирования некоторых данных, в зависимости от функции агрегирования, и кроме того, что вам нужно поместить столбец или столбцы, в которые нужно группировать.

например:

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

Это приведет к максимальной зарплате департаментов.

Теперь, если мы опускаем d.deptno из предложения group by, это выдаст ту же ошибку.

0 голосов
/ 23 марта 2017

Та же ошибка возникает и тогда, когда ключевое слово UPPER или LOWER не используется ни в месте выражения, ни в группе по выражению.

Неправильно: -

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

Справа: -

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