logi sisse meist KKK

See peaks olema lihtne, aga ei saa üle ega ümber :/ Kui MySql-is saab gruppida ühe välja järgi: näiteks

SELECT V1, V2 FROM T1 GROUP BY V1

Paistab et teistes andmebaasides see nii lihtsalt ei käi, GROUP BY peab sisaldama samu välju mis SELECT näit.

SELECT V1, V2 FROM T1 GROUP BY V1, V2

(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.

küsitud Dec 29 '11 at 13:00

curate's gravatar image

curate
92


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 = 1
ja vist isegi
SELECT * FROM T WHERE ROW_NUMBER() OVER (PARTITION BY V1) = 1
aga 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 V1 iga väärtuse piires unikaalne, saab teha

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.

link

vastatud Dec 31 '11 at 03:14

Ahto%20Truu's gravatar image

Ahto Truu ♦♦
5741711

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:

SELECT V1, MAX(V2) FROM T1 GROUP BY V1

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:

SELECT DISTINCT ON (V1) V1, V2, V3, V4, V5 FROM T1 ORDER BY V1, V2

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.

link

vastatud Dec 29 '11 at 13:10

Tambet%20Matiisen's gravatar image

Tambet Matiisen ♦♦
6723925

edited Dec 29 '11 at 13:50

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

link

vastatud Jan 17 at 12:59

Kuido%20K%C3%BClm's gravatar image

Kuido Külm
1

Sinu vastus
toggle preview

Jälgi seda küsimust

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or __italic__
  • **bold** or __bold__
  • link:[tekst](http://url.com/ "pealkiri")
  • pilt?![alt tekst](/path/img.jpg "pealkiri")
  • nummerdatud nimekiri: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Pinu tööpakkumised

kõik pakkumised »

Sildid:

×10
×3
×1

küsitud: Dec 29 '11 at 13:00

nähtud: 567 korda

viimati uuendatud: Jan 17 at 12:59

Litsents: Creative Commons Attribution License | Kontakt: info@pinu.ee