2009-10-05 3 views
96

Je reçois ORA-00979 avec la requête suivante:ORA-00979 pas un groupe par l'expression

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 ne pouvais pas trouver des exemples qui ont tous les deux GROUP BY et ORDER BY clauses dans la même requête. J'ai essayé d'enlever chaque champ du groupe par un à la fois, mais je reçois toujours la même erreur.

Répondre

166

Vous devez mettre sur eux qui compriment les résultats à une seule valeur toutes les colonnes du SELECT dans les fonctions GROUP BY ou utilisation (comme MIN, MAX ou SUM).

Un exemple simple de comprendre pourquoi cela se produit: Imaginez que vous avez une base de données comme ceci:

FOO BAR 
0 A 
0 B 

et que vous exécutez SELECT * FROM table GROUP BY foo. Cela signifie que la base de données doit retourner une seule ligne comme résultat avec la première colonne 0 pour remplir le GROUP BY mais il y a maintenant deux valeurs de bar à choisir. Quel résultat attendez-vous - A ou B? Ou la base de données doit-elle renvoyer plus d'une ligne, en violation du contrat GROUP BY?

+0

même ceux qui sont dans la clause ORDER BY? Je n'ai pas ces deux dans mon groupe. – Theresa

+6

Non, vous n'avez pas besoin de les mettre dans votre commande par la clause – Xaisoft

+2

J'ai essayé d'ajouter les deux colonnes dans le ORDER BY au GROUP BY. Ça a marché. Merci! – Theresa

13

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

2

Dommage que Oracle a des limitations comme celles-ci. Bien sûr, le résultat d'une colonne qui n'est pas dans GROUP BY serait aléatoire, mais parfois vous le souhaitez. Oracle stupide, vous pouvez le faire dans MySQL/MSSQL.

mais il y a un travail autour pour Oracle:

Alors 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 quelques 0 est comme suit, pour garder votre colonne portée , mais pas le groupe par celui-ci (en supposant ces chiffres sont, 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); 
+0

@GlennFromIowa étant donné que ma pseudo-table n'est pas rigoureusement définie ci-dessus, et que je ne travaille plus pour une entreprise avec 11g, je ne peux pas donner un meilleur exemple, même si cela a été un problème lors de mon dernier test. –

+1

Juste par curiosité qu'est-ce qu'un exemple de quand vous voulez un résultat aléatoire? Je ne peux pas penser à une raison que vous voudriez regrouper par FOO et obtenir une rangée aléatoire pour BAR. –

1

Le groupe en est utilisé pour agréger de manière me données, en fonction de la fonction d'agrégat, et autre que cela, vous devez mettre une colonne ou des colonnes pour lesquelles vous avez besoin du regroupement.

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 les services de salaire maximum.

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

1

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; 
0

même erreur vient aussi quand UPPER ou INFÉRIEUR mot-clé non utilisé à la fois dans l'expression et sélectionnez le groupe par l'expression.

Mauvais: -

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

droit: -

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

Si vous ne tâtons en vertu d'inclure la clause GROUP BY, toute expression dans SELECT, ce qui est fonction de groupe (ou fonction agrégée ou colonne agrégée), par exemple COUNT, AVG, MIN, MAX, SUM et ainsi de suite (List of Aggregate functions) devrait être présent dans la clause GROUP BY.

Exemple (de manière correcte) (ici employee_id n'est pas fonction de groupe (colonne non agrégée), de sorte qu'il doit apparaissent dans GROUP BY. En revanche, la somme (salaire) est une fonction de groupe (colonne agrégée), il est donc pas tenu de figurer dans la clause GROUP BY.

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

Exemple (mauvais sens) (ici employee_id n'est pas fonction de groupe et il ne semble pas GROUP BY clause, ce qui conduira à l'ORA-00979 Erreur

SELECT employee_id, sum(salary) 
    FROM employees; 

Pour vous corriger devez faire un des éléments suivants:

  • Inclure toutes les expressions non agrégées figurant dans SELECT clause du GROUP BY clause
  • Supprimer la fonction de groupe (global) à partir de la clause SELECT.