web-dev-qa-db-fra.com

ORA-00979 n'est pas un groupe par expression

Je reçois ORA-00979 avec la requête suivante:

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;

Je n'ai trouvé aucun exemple contenant les deux clauses GROUP BY et ORDER BY dans la même requête. J'ai essayé de supprimer chaque champ du groupe, un par un, mais j'obtiens toujours la même erreur.

121
Theresa

Vous devez mettre toutes les colonnes de la SELECT dans le GROUP BY ou utiliser des fonctions qui compressent les résultats en une seule valeur (comme MIN, MAX ou SUM).

Un exemple simple pour comprendre pourquoi cela se produit: Imaginez que vous ayez une base de données comme celle-ci:

FOO BAR
0   A
0   B

et vous exécutez SELECT * FROM table GROUP BY foo. Cela signifie que la base de données doit renvoyer une seule ligne comme résultat avec la première colonne 0 pour remplir le GROUP BY, mais il existe désormais deux valeurs de bar parmi lesquelles choisir. Quel résultat attendriez-vous - A ou B? Ou la base de données doit-elle renvoyer plusieurs lignes en violation du contrat GROUP BY?

206
Aaron Digulla

Incluez dans la clause GROUP BY toutes les expressions SELECT qui ne sont pas des arguments de fonction de groupe. 

15
Xaisoft

Dommage que Oracle ait de telles limitations. Bien sûr, le résultat pour une colonne ne figurant pas dans GROUP BY serait aléatoire, mais parfois vous le souhaitez. Silly Oracle, vous pouvez le faire avec MySQL/MSSQL.

MAIS il y a un travail autour pour Oracle:

Bien que la ligne suivante ne fonctionne pas

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

Vous pouvez tromper Oracle avec des 0 comme le suivant, pour garder votre colonne dans le champ, mais pas pour la grouper par celle-ci (en supposant qu'il s'agisse de nombres, sinon utilisez 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);
6
Joseph Lust

Vous devriez faire ce qui suit: 

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;
2
Pavel Zimogorov

Le groupe par est utilisé pour agréger certaines données, en fonction de la fonction d'agrégation, et vous devez indiquer une ou plusieurs colonnes sur lesquelles vous avez besoin du groupement.

par exemple: 

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

Cela se traduira par le salaire maximum des départements.

Maintenant, si nous omettons la clause d.deptno de group by, la même erreur se produira.

1
Muhammad Nadeem

Si vous tâtonnez en incluant la clause GROUP BY, toute expression dans SELECT, qui n'est pas une fonction de groupe (ou une fonction d'agrégat ou une colonne agrégée) telle que COUNT, AVG, MIN, MAX, SUM et ainsi de suite ( Liste des fonctions agrégées ) devrait être présent dans la clause GROUP BY.

Exemple (manière correcte) (ici employee_id n'est pas une fonction de groupe (colonne non agrégée), de sorte qu'il doit apparaître dans GROUP BY. En revanche, sum (salaire) est une fonction de groupe ), il n’est donc pas nécessaire d’apparaître dans la clause GROUP BY.

   SELECT employee_id, sum(salary) 
   FROM employees
   GROUP BY employee_id; 

Exemple (dans le mauvais sens) (ici employee_id n'est pas une fonction de groupe et n'apparaît pas dans la clause GROUP BY, ce qui entraînerait une erreur ORA-00979.

   SELECT employee_id, sum(salary) 
   FROM employees;

Pour corriger vous devez faire un de ce qui suit:

  • Inclure toutes les expressions non agrégées répertoriées dans la clause SELECT dans la clause GROUP BY
  • Supprimer la fonction de groupe (agrégat) de la clause SELECT.
1
fg78nc

Outre les autres réponses, cette erreur peut survenir en cas d'incohérence dans une clause order by. Par exemple:

select 
    substr(year_month, 1, 4)
    ,count(*) as tot
from
    schema.tbl
group by
    substr(year_month, 1, 4)
order by
    year_month
0
Mike Palmice

La même erreur survient également lorsqueSUPÉRIEURouINFÉRIEURmot clé non utilisé à la fois dans l'expression sélectionnée et dans le groupe d'expression.

Faux :-

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

Droite :-

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