ORA-00979 не группа по выражению

147

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

Есть
источник

Ответы:

232

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

Аарон Дигулла
источник
7
Нет, вам не нужно помещать их в ваш заказ по пункту
Xaisoft
3
Я попытался добавить два столбца в ORDER BY в GROUP BY. Это сработало. Спасибо!
Тереза
1
Или, говоря иначе: если у вас есть два столбца и группа по первому, это означает, что у вас будет несколько значений из второго столбца на строку результатов. Так как есть только одна строка результата, но много значений для выбора, какое из них должно вернуть БД? Первый это натыкается на?
Аарон Дигулла
6
@AaronDigulla Это то, что MySQL делает, и мир не закончился: p
Крис Бейкер
1
Я частично согласен. Но предположим следующий случай: есть 4 столбца: A, B, C и D. Теперь я установил (A, B, C) в качестве составного ключа. Тогда «выберите A, B, max (C), D ... group by A, B» не является неоднозначным, поскольку для каждой комбинации A, B и C, D уже определено. Тем не менее оракул отказывается выполнять свою работу.
га
17

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

Xaisoft
источник
9

Жаль, что у 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);
Джозеф Ласт
источник
@GlennFromIowa, учитывая, что моя псевдо-таблица строго не определена выше, и что я больше не работаю в фирме с 11g, я не могу предоставить лучший пример, хотя это было проблемой, когда я в последний раз проверял ее.
Джозеф Ласт
4
Просто из любопытства, что является примером того, когда вы хотите получить случайный результат? Я не могу придумать причину, по которой вы хотите сгруппировать по FOO и получить случайную строку для BAR.
Кайл Бриденстайн
4

Если группировка в силу в том числе GROUP BYпункт, любое выражение SELECT, которое не является функцией группы (или агрегатной функции или агрегированных колонки) , такие как COUNT, AVG, MIN, MAX, SUMи так далее ( список агрегатных функций ) должны присутствовать в GROUP BYстатье.

Пример (правильный путь) (здесь employee_idэто не групповая функция (неагрегированный столбец), поэтому она должна отображаться в GROUP BY. Напротив, сумма (зарплата) является групповой функцией (агрегированный столбец), поэтому ее не требуется отображать в 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предложения.
fg78nc
источник
2

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

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

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

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

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

Правильно :-

select UPPER(a) , count(*) from my_table group by UPPER(a) .
Opster Elasticsearch Pro-Vijay
источник
1

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

например:

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

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

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

Мухаммед Надим
источник
1

В дополнение к другим ответам, эта ошибка может возникнуть, если есть несоответствие в предложении 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
3pitt
источник