|
See peaks olema lihtne, aga ei saa üle ega ümber :/ Kui MySql-is saab gruppida ühe välja järgi: näiteks
Paistab et teistes andmebaasides see nii lihtsalt ei käi, GROUP BY peab sisaldama samu välju mis SELECT näit.
(sellisel juhul on tulemus hoopis teine) Mis trikiga ma saaks gruppida ainult ühe välja järgi, samas oleks vaja kätte saada kõik väljad? Üritan seda saavutada Firebird-is: http://www.firebirdsql.org/ Arvatavasti samad standardid ka teistes RDMS andmebaasides. |
|
Kui on vaja saada kõik ülejäänud väljad samast kirjest ja on ükskõik, millisest, peaks standardi järgi saama teha SELECT V1, V2, V3, ... FROM (SELECT V1, V2, V3, ..., ROW_NUMBER() OVER (PARTITION BY V1) AS X FROM T) WHERE X = 1ja vist isegi SELECT * FROM T WHERE ROW_NUMBER() OVER (PARTITION BY V1) = 1aga Tracker laseb arvata, et selliste konstruktsioonide tugi tuleb Firebirdi versioonis 3.0. Seni on alternatiivne lahendus teha SELECT * FROM T WHERE (V1, V2, V3, ...) IN (SELECT V1, V2, V3, ... FROM T AS X WHERE X.V1 = T.V1 ROWS 1 TO 1)kus V2, V3, ... on selline väljade komplekt, et need kokku on V1 iga väärtuse piires unikaalsed.
Kui ülejäänud väljade hulgas on mõni, mis on ka üksi SELECT * FROM T WHERE (V1, V2) IN (SELECT V1, MIN(V2) FROM T GROUP BY V1)mis võib olla eelmisest efektiivsem, eriti kui tabelil T on väljadepaari (V1, V2) peal indeks.
Ahjaa, kui tulemusse ühe liigse veeru saamine ei sega, siis võib kõige esimest päringut natuke lihtsustada: SELECT T.*, ROW_NUMBER() OVER (PARTITION BY V1) AS X FROM T WHERE X = 1
(Dec 31 '11 at 03:19)
Ahto Truu ♦♦
|
|
Ei oska Firebirdi kohta konkreetselt öelda, aga üldiselt eeldatakse jah, et GROUP BY-st välja jäävate väljade puhul tuleb mingit agregaatfunktsiooni kasutada. Näiteks:
Siin võib tekkida probleem, kui tahad lisaks V2 väljale ka V3, V4 ja V5 väljasid. Kui rakendad kõigile nt MAX() agregaatfunktsiooni, siis võib iga väli pärineda erinevast kirjest. Mõnikord pole see probleem, kui tead, et sama V1 korral on kõigil teistel väljadel alati sama väärtus. Aga kui see nii ei ole, siis on erinevatel andmebaasisüsteemidel erinevad häkid sellega toimetulekuks. PostgreSQL-s teeks sellisel juhul nii:
Sellisel juhul pärinevad V1, V2, V3, V4 ja V5 kõik samast kirjest. Millisest, see on määratud ORDER BY poolt - esimene kõigist sama V1 väärtusega kirjetest, antud juhul siis vähima V2 väärtusega. Tänud Tambet! Katsetasin, jah MAX() ei saa kasutada, kuna on vaja konkreetse rea andmeid. Proovisin agregaatfunktsioone FIRST(), LAST() paistab et need on Firebirdile tundmatud, puuduvad ka dokumentatsioonis. SELECT DISTINCT ON (V1) Väljastab errori, ON ei meeldi. SELECT DISTINCT (V1)FROM ... Töötab, aga tahaks ka teisi välju V2, V3... SELECT DISTINCT (V1), V2, V3, V4, V5 FROM T1 ORDER BY V1, V2 Väljastab kogu sisu, ehk ei gruppi V1 järgi.
(Dec 30 '11 at 13:58)
curate
|
|
Self-correlated subquery SELECT [ACCOUNT_DETAILS].ACCOUNT_ID, [ACCOUNT_DETAILS].SERVICES_ID, (SELECT SUM(AT.TOTAL_SUMMA) FROM [dbo].[ACCOUNT_DETAILS] AT WHERE AT.ACCOUNT_ID = ACCOUNT_DETAILS.ACCOUNT_ID) AS TOTAL_SUMMA FROM [dbo].[ACCOUNT_DETAILS] arvutab iga [ACCOUNT_DETAILS].ACCOUNT_ID, [ACCOUNT_DETAILS].SERVICES_ID rea kohta summa (SELECT SUM(AT.TOTAL_SUMMA) FROM [dbo].[ACCOUNT_DETAILS] AT WHERE AT.ACCOUNT_ID = ACCOUNT_DETAILS.ACCOUNT_ID) AS TOTAL_SUMMA |
