ORA-00979 keine Gruppe nach Ausdruck

147

Ich erhalte ORA-00979 mit der folgenden Abfrage:

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;

Ich konnte keine Beispiele finden, die sowohl GROUP BY- als auch ORDER BY-Klauseln in derselben Abfrage enthielten. Ich habe versucht, jedes Feld einzeln aus der Gruppe zu entfernen, erhalte jedoch immer noch den gleichen Fehler.

Da ist ein
quelle

Antworten:

232

Sie müssen alle Spalten des Put SELECTin dem GROUP BYoder auf sie verwenden Funktionen , die die Ergebnisse auf einen einzelnen Wert (wie komprimieren MIN, MAXoder SUM).

Ein einfaches Beispiel, um zu verstehen, warum dies passiert: Stellen Sie sich vor, Sie haben eine Datenbank wie diese:

FOO BAR
0   A
0   B

und du rennst SELECT * FROM table GROUP BY foo. Dies bedeutet, dass die Datenbank eine einzelne Zeile als Ergebnis mit der ersten Spalte zurückgeben muss 0, um die zu erfüllen, GROUP BYaber es stehen jetzt zwei Werte barzur Auswahl. Welches Ergebnis würden Sie erwarten - Aoder B? Oder sollte die Datenbank mehr als eine Zeile zurückgeben, was gegen den Vertrag von verstößt GROUP BY?

Aaron Digulla
quelle
7
Nein, Sie müssen sie nicht per Klausel in Ihre Bestellung aufnehmen
Xaisoft
3
Ich habe versucht, die beiden Spalten in ORDER BY zur GROUP BY hinzuzufügen. Das hat funktioniert. Vielen Dank!
Theresa
1
Oder anders ausgedrückt: Wenn Sie zwei Spalten haben und nach der ersten gruppieren, bedeutet dies, dass Sie pro Ergebniszeile mehrere Werte aus der zweiten Spalte haben. Da nur eine einzige Ergebniszeile, aber viele Werte zur Auswahl stehen, welche sollte die DB zurückgeben? Das erste, über das es stolpert?
Aaron Digulla
6
@ AaronDigulla Das ist, was MySQL tut, und die Welt ist nicht untergegangen: p
Chris Baker
1
Ich stimme teilweise zu. Nehmen wir jedoch den folgenden Fall an: Es gibt 4 Spalten: A, B, C und D. Jetzt setze ich (A, B, C) als zusammengesetzten Schlüssel. Dann ist "A, B, max (C), D ... nach A, B auswählen" nicht mehrdeutig, da für jede Kombination von A, B und C D bereits definiert ist. Noch immer weigert sich Orakel, seinen Job zu machen.
ga
17

Nehmen Sie GROUP BYalle SELECTAusdrücke in die Klausel auf , die keine Gruppenfunktionsargumente sind.

Xaisoft
quelle
9

Schade, dass Oracle solche Einschränkungen hat. Sicher, das Ergebnis für eine Spalte, die nicht in GROUP BY enthalten ist, ist zufällig, aber manchmal möchten Sie das. Dummes Oracle, das kannst du in MySQL / MSSQL.

ABER es gibt eine Problemumgehung für Oracle:

Während die folgende Zeile nicht funktioniert

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

Sie können Oracle mit einigen Nullen wie den folgenden austricksen, um Ihre Spalte im Gültigkeitsbereich zu halten, aber nicht danach zu gruppieren (vorausgesetzt, dies sind Zahlen, andernfalls verwenden Sie 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);
Joseph Lust
quelle
@GlennFromIowa Da meine Pseudotabelle oben nicht genau definiert ist und ich nicht mehr für eine Firma mit 11 g arbeite, kann ich kein besseres Beispiel liefern, obwohl es ein Problem war, als ich es das letzte Mal getestet habe.
Joseph Lust
4
Was ist ein Beispiel dafür, wann Sie aus Neugier ein zufälliges Ergebnis wünschen würden? Ich kann mir keinen Grund vorstellen, warum Sie nach FOO gruppieren und eine zufällige Zeile für BAR erhalten möchten.
Kyle Bridenstine
4

Wenn Sie auf Grund einschließlich keine Gruppierung GROUP BYKlausel, jeden Ausdruck in SELECT, die keine Gruppenfunktion (oder Aggregatfunktion oder aggregierte Spalte) wie COUNT, AVG, MIN, MAX, SUMund so weiter ( Liste der Aggregatfunktionen ) sollten in vorliegen GROUP BYKlausel.

Beispiel (korrekter Weg) (hier employee_idist keine Gruppenfunktion (nicht aggregierte Spalte), daher muss sie in erscheinen GROUP BY. Im Gegensatz dazu ist sum (Gehalt) eine Gruppenfunktion (aggregierte Spalte), sodass es nicht erforderlich ist, in der GROUP BYKlausel zu erscheinen .

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

Beispiel (falscher Weg) (hier employee_idist keine Gruppenfunktion und sie erscheint nicht in der GROUP BYKlausel, was zum ORA-00979-Fehler führt.

   SELECT employee_id, sum(salary) 
   FROM employees;

Um dies zu korrigieren, müssen Sie einen der folgenden Schritte ausführen:

  • Schließen Sie alle nicht aggregierten Ausdrücke, die in der SELECTKlausel aufgeführt sind , in die GROUP BYKlausel ein
  • Entfernen Sie die Gruppenfunktion (Aggregatfunktion) aus der SELECTKlausel.
fg78nc
quelle
2

Sie sollten Folgendes tun:

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;
Pavel Zimogorov
quelle
1

Der gleiche Fehler tritt auch auf, wenn das Schlüsselwort UPPER oder LOWER nicht an beiden Stellen im ausgewählten Ausdruck und in der Gruppe nach Ausdruck verwendet wird.

Falsch :-

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

Richtig :-

select UPPER(a) , count(*) from my_table group by UPPER(a) .
Opster Elasticsearch Pro-Vijay
quelle
1

Die Gruppierung nach wird verwendet, um einige Daten abhängig von der Aggregatfunktion zu aggregieren. Ansonsten müssen Sie Spalten oder Spalten einfügen, für die Sie die Gruppierung benötigen.

beispielsweise:

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

Dies führt zu einem maximalen Gehalt der Abteilungen.

Wenn wir nun die d.deptnoKlausel from group by weglassen , wird derselbe Fehler ausgegeben.

Muhammad Nadeem
quelle
1

Zusätzlich zu den anderen Antworten kann dieser Fehler auftreten, wenn eine order by-Klausel inkonsistent ist. Zum Beispiel:

select 
    substr(year_month, 1, 4)
    ,count(*) as tot
from
    schema.tbl
group by
    substr(year_month, 1, 4)
order by
    year_month
3pitt
quelle