ORA-00979 geen groeperen op uitdrukking

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 SELECTin de GROUP BYplaatsen of er functies op gebruiken die de resultaten comprimeren tot een enkele waarde (zoals MIN, MAXof 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 foouit. Dit betekent dat de database een enkele rij als resultaat moet retourneren met de eerste kolom 0om aan de GROUP BYte voldoen, maar er zijn nu twee waarden van barom uit te kiezen. Welk resultaat zou je verwachten – Aof 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, SUMenzovoort (Lijst met geaggregeerde functies) moet aanwezig zijn in GROUP BY-clausule.

Voorbeeld (juiste manier)(hier is employee_idgeen 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 BYclausule te verschijnen.

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

Voorbeeld (verkeerd)(hier employee_idis 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.deptnogroep voor clausule weglaten, geeft het dezelfde fout.

Other episodes