Sobes.tech
Junior

Kas peab olema SELECT-lause sees, et GROUP BY operaator töötaks?

sobes.tech AI

Vastus AI-lt

Jah, enamikus relatsioonandmebaasides (SQL) peavad välja, mis on märgitud SELECT-is (välja ar agregaatfunktsioonide), olema GROUP BY-s.

Selgitus:

GROUP BY-ga rühmitab see rida, mille väärtused on samad määratud veergudes, üheks rida. SELECT-i kaudu määratakse, millised veerud kuvatakse tulemusena. Selleks, et SELECT saaks õigesti kuvada iga rühma väärtused, peavad kõik mitte-agregaatveerud olema GROUP BY-s määratud veergude osana. Vastasel juhul ei tea süsteem, millist väärtust näidata.

Näide:

Vaatleme Orders tabelit veergudega CustomerID, OrderDate, Amount.

CustomerID OrderDate Amount
1 2023-01-01 100
1 2023-01-15 200
2 2023-01-05 150

Kui soovime saada iga kliendi tellimuste kogusumma, kasutame GROUP BY CustomerID:

SELECT CustomerID, SUM(Amount)
FROM Orders
GROUP BY CustomerID;

Tulemus:

CustomerID SUM(Amount)
1 300
2 150

Siin on CustomerID nii SELECT-is kui ka GROUP BY-s. SUM(Amount) on agregaatfunktsioon ja ei nõua GROUP BY-s osalemist.

Vigane päring:

Kui proovime lisada OrderDate SELECT-i ilma selle GROUP BY-s osalemiseta:

SELECT CustomerID, OrderDate, SUM(Amount)
FROM Orders
GROUP BY CustomerID;

See päring põhjustab vea, kuna CustomerID = 1 puhul on kaks erinevat OrderDate väärtust (2023-01-01 ja 2023-01-15), ning süsteem ei tea, millist neist näidata.

Selleks, et see päring oleks korrektne, kas eemaldage OrderDate SELECT-ist või lisage see GROUP BY-sse:

SELECT CustomerID, OrderDate, SUM(Amount)
FROM Orders
GROUP BY CustomerID, OrderDate;

Erandid / süntaksivõimalused (olenevalt SDB-st):

Mõnes SDB-s (näiteks SQLite) on paindlikumad reeglid, mis võimaldavad lisada SELECT-i mitte-agregaatveerge ilma nende GROUP BY-s osalemiseta, kui need veerud on funktsionaalselt sõltuvad GROUP BY-s olevatest veergudest (näiteks, kui CustomerID on PRIMARY KEY ja määrab kõik teised tabeliveerud). Kuid see ei ole SQL-i standard ja võib põhjustada ootamatuid tulemusi teistes süsteemides. Seetõttu on parem järgida üldist reeglit.