Ik krijg ORA-00979 met de volgende vraag:
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;
Ik kon geen voorbeelden vinden die zowel GROUP BY- als ORDER BY-clausules in dezelfde query hadden. Ik heb geprobeerd elk veld één voor één uit de groep te verwijderen, maar ik krijg nog steeds dezelfde foutmelding.
Antwoord 1, autoriteit 100%
U moet alle kolommen van de SELECT
in de GROUP BY
plaatsen of er functies op gebruiken die de resultaten comprimeren tot een enkele waarde (zoals MIN
, MAX
of SUM
).
Een eenvoudig voorbeeld om te begrijpen waarom dit gebeurt: stel je voor dat je een database hebt zoals deze:
FOO BAR
0 A
0 B
en je voert SELECT * FROM table GROUP BY foo
uit. Dit betekent dat de database een enkele rij als resultaat moet retourneren met de eerste kolom 0
om aan de GROUP BY
te voldoen, maar er zijn nu twee waarden van bar
om uit te kiezen. Welk resultaat zou je verwachten – A
of B
? Of moet de database meer dan één rij retourneren, in strijd met het contract van GROUP BY
?
Antwoord 2, autoriteit 8%
Neem in de GROUP BY
-clausule alle SELECT
-expressies op die geen groepsfunctieargumenten zijn.
Antwoord 3, autoriteit 3%
Jammer dat Oracle dergelijke beperkingen heeft. Natuurlijk zou het resultaat voor een kolom die niet in de GROUP BY staat willekeurig zijn, maar soms wil je dat. Silly Oracle, je kunt dit doen in MySQL/MSSQL.
MAAR er is een oplossing voor Oracle:
Terwijl de volgende regel niet werkt
SELECT unique_id_col, COUNT(1) AS cnt FROM yourTable GROUP BY col_A;
Je kunt Oracle misleiden met enkele nullen, zoals de volgende, om je kolom binnen het bereik te houden, maar er niet op te groeperen (ervan uitgaande dat dit getallen zijn, gebruik anders 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);
Antwoord 4, autoriteit 2%
Als u groepeert op grond van het opnemen van de GROUP BY
-clausule, elke uitdrukking in SELECT
, die geen groepsfunctie (of aggregatiefunctie of geaggregeerde kolom) is, zoals COUNT
, AVG
, MIN
, MAX
, SUM
enzovoort (Lijst met geaggregeerde functies) moet aanwezig zijn in GROUP BY
-clausule.
Voorbeeld (juiste manier)(hier is employee_id
geen groepsfunctie (niet-geaggregeerde kolom), dus moetverschijnen in GROUP BY
. Daarentegen is sum(salary) een groepsfunctie (geaggregeerde kolom), dus het is niet verplicht om in de GROUP BY
clausule te verschijnen.
SELECT employee_id, sum(salary)
FROM employees
GROUP BY employee_id;
Voorbeeld (verkeerd)(hier employee_id
is geen groepsfunctie en komt niet voor in de GROUP BY
-clausule, wat zal leiden tot de ORA-00979-fout .
SELECT employee_id, sum(salary)
FROM employees;
Om te corrigeren moet u eenvan het volgende doen:
- Neem alle niet-geaggregeerde expressies op die worden vermeld in de
SELECT
-clausule in de
GROUP BY
-clausule - Verwijder de groepsfunctie (aggregaat) uit de
SELECT
-clausule.
Antwoord 5
U moet het volgende doen:
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;
Antwoord 6
Dezelfde fout treedt ook op wanneer het trefwoord UPPERof LOWERniet op beide plaatsen wordt gebruikt in de geselecteerde uitdrukking en groepeer op uitdrukking .
Fout:-
select a , count(*) from my_table group by UPPER(a) .
Juist:-
select UPPER(a) , count(*) from my_table group by UPPER(a) .
Antwoord 7
In aanvulling op de andere antwoorden, kan deze fout optreden als er een inconsistentie is in een volgorde per clausule. Bijvoorbeeld:
select
substr(year_month, 1, 4)
,count(*) as tot
from
schema.tbl
group by
substr(year_month, 1, 4)
order by
year_month
Antwoord 8
De groeperen op wordt gebruikt om bepaalde gegevens te aggregeren, afhankelijk van de aggregatiefunctie, en behalve dat moet u de kolom of kolommen plaatsen waaraan u de groepering wilt toevoegen.
bijvoorbeeld:
select d.deptno, max(e.sal)
from emp e, dept d
where e.deptno = d.deptno
group by d.deptno;
Dit resulteert in het maximumsalaris van de afdelingen.
Als we nu de d.deptno
groep voor clausule weglaten, geeft het dezelfde fout.