Avatar billede bernhof Nybegynder
23. august 2004 - 22:07 Der er 16 kommentarer og
1 løsning

Avanceret SQL query

Her er en lille ekspertnød til dem, som har styr på deres SQL (her taler vi god gammeldags Access og ikke noget fancy MS SQL el. lign. :)

Til at starte med vil jeg give et simpelt eksempel på mit problem, og se om et forslag til løsningen på dette kan overføres til det virkelige problem (som omfatter en del flere tabeller og felter), eller om jeg senere hen må blive nødt til at spørge noget mere.

** TABELLER

"tblAnnonce" med felterne:
- id (autonummer, primary key)
- overskrift (tekst)
- type (tal, henviser til et id fra tblType)

"tblBillede" med felterne:
- id (autonummer, primary key)
- annonce (tal, henviser til et id fra tblAnnonce)
- filnavn (tekst)
- hovedbillede (boolean)

"tblType" med felterne:
- id (autonummer, primary key)
- navn (tekst)

** ET EKSEMPEL

tblType:
---------
id  navn
1    type1
2    type2

tblAnnonce:
-------------
id  overskrift    type
1    an1            2
2    an2            1
3    an3            1

tblBillede:
-----------
id  annonce  filnavn          hovedbillede
1    2            billede1.jpg    False 
2    2            billede2.jpg    True
3    1            billede3.jpg    False
4    1            billede4.jpg    False

** HVAD SKAL HENTES?

Den ønskede SQL query skal returnere en liste over annoncer med følgende data:
1. Annoncens id og overskrift
2. Annoncens type (navnet på denne)
3. Antal billeder der henviser til annoncen
4. Filnavnet på det billede der henviser til annoncen med værdien hovedbillede = True
MEN!! Hvis ingen af billederne, der henviser til annoncen, har værdien hovedbillede = True, så skal den bare tage "det første og bedste" billede der henviser til annoncen, dvs. billedet med lavest id.

** RESULTAT

id  overskrift  type      antalbilleder    filnavn
1    an1            type2    2                  billede3.jpg
2    an2            type1    2                  billede2.jpg
3    an3            type1    0                  (null)

Som I kan se, får vi "billede3.jpg" til annonce 1, da ingen af billederne til denne annonce har værdien hovedbillede = True, og billede 3 er derfor "det første og det bedste". Derimod får vi "billede2.jpg" til annonce 2, da dette har værdien hovedbillede = True.

** LØSNINGSFORSLAG

For god ordens skyld vil jeg lige komme med et løsningsforslag, så I kan tage den derfra.

SELECT tblAnnonce.id, tblAnnonce.overskrift, tblType.navn, COUNT(tblBillede.annonce) AS AntalBilleder FROM (tblAnnonce INNER JOIN tblType ON tblAnnonce.type = tblType.id) LEFT JOIN tblBillede ON tblBillede.annonce = tblAnnonce.id GROUP BY tblAnnonce.id, tblAnnonce.overskrift, tblType.navn

Ovenstående klarer punkt 1-3, men løsningen af punkt 4 kan jeg ikke gennemskue. Det håber jeg I kan :)

På forhånd tak for hjælpen! - Mikkel
Avatar billede uffe_kld Nybegynder
23. august 2004 - 22:27 #1
Jeg er ikke sikker på det virker, men jeg prøve følgende:

SELECT tblAnnonce.id, tblAnnonce.overskrift, tblType.navn, COUNT(tblBillede.annonce) AS AntalBilleder, first (filnavn) FROM (tblAnnonce INNER JOIN tblType ON tblAnnonce.type = tblType.id) LEFT JOIN tblBillede ON tblBillede.annonce = tblAnnonce.id GROUP BY tblAnnonce.id, tblAnnonce.overskrift, tblType.navn, tblbillede.hovedbillede
Avatar billede uffe_kld Nybegynder
23. august 2004 - 22:29 #2
Jeg retter lige lidt:

Jeg er ikke sikker på det virker, men jeg prøve følgende:

SELECT tblAnnonce.id, tblAnnonce.overskrift, tblType.navn, COUNT(tblBillede.annonce) AS AntalBilleder, first (filnavn) FROM (tblAnnonce INNER JOIN tblType ON tblAnnonce.type = tblType.id) LEFT JOIN tblBillede ON tblBillede.annonce = tblAnnonce.id GROUP BY tblAnnonce.id, tblAnnonce.overskrift, tblType.navn, tblbillede.hovedbillede, tblbillede.id
Avatar billede bernhof Nybegynder
23. august 2004 - 22:38 #3
Jeg får fejlen: "You tried to execute a query that does not include the specified expression 'billede_navn' as part of an aggregate function."

Tilføjer jeg billede_navn til GROUP BY-delen, får jeg fejlen: "No current record."

Fjerner jeg billede_top fra GROUP BY-delen, og lader billede_navn stå, får jeg ingen fejl, men til gengæld får jeg også annonce 1 og 2 vist 2 gange -- én gang for hvert billede der henviser til annoncerne :)
Avatar billede bernhof Nybegynder
23. august 2004 - 22:39 #4
Tester lige din rettelse..
Avatar billede bernhof Nybegynder
23. august 2004 - 22:40 #5
Jeg får førstnævnte fejl "You tried ...", hvis jeg forsøger mig med dit forslag nr. 2.
Avatar billede bernhof Nybegynder
23. august 2004 - 22:49 #6
hovsa - jeg fik vist lige brugt de forkerte felt-navne :) i ovenstående - det skulle se således ud:

Jeg får fejlen: "You tried to execute a query that does not include the specified expression 'filnavn' as part of an aggregate function."

Tilføjer jeg filnavn til GROUP BY-delen, får jeg fejlen: "No current record."

Fjerner jeg hovedbillede fra GROUP BY-delen, og lader filnavn stå, får jeg ingen fejl, men til gengæld får jeg også annonce 1 og 2 vist 2 gange -- én gang for hvert billede der henviser til annoncerne :)
Avatar billede uffe_kld Nybegynder
23. august 2004 - 23:09 #7
jeg prøver igen :)

SELECT tblAnnonce.id, tblAnnonce.overskrift, tblType.navn, COUNT(tblBillede.annonce) AS AntalBilleder, first (filnavn) FROM (tblAnnonce INNER JOIN tblType ON tblAnnonce.type = tblType.id) LEFT JOIN tblBillede ON tblBillede.annonce = tblAnnonce.id GROUP BY tblAnnonce.id, tblAnnonce.overskrift, tblType.navn
ORDER BY tblAnnonce.id, tblbillede.hovedbillede, tblbillede.id
Avatar billede bernhof Nybegynder
23. august 2004 - 23:50 #8
Det ser fornuftigt ud med den ORDER BY-del, men jeg får fejlen: "You tried to execute a query that does not include the specified expression 'tblBillede.hovebillede' as part of an aggregate function."

Tilføjer jeg tblBillede.hovedbillede til GROUP BY-delen, får jeg samme fejl, bare med tblBillede.id. Tilføjer jeg så også tblBillede.id til GROUP BY-delen, får jeg fejlen "No current record".
Avatar billede bernhof Nybegynder
23. august 2004 - 23:54 #9
Har lagt eksempel-databasen op på adressen: http://drunkencow.dk/test.mdb.rename
Omdøb til "test.mdb"
Avatar billede uffe_kld Nybegynder
24. august 2004 - 07:36 #10
Nu tror jeg den er der.

SELECT tblAnnonce.id, tblAnnonce.overskrift, tblType.navn, Count(qBillede.filnavn) AS AntalBilleder, First(qBillede.filnavn) AS FørsteOffilnavn
FROM (tblAnnonce INNER JOIN tblType ON tblAnnonce.type = tblType.id) LEFT JOIN  (select * from tblBillede ORDER BY hovedbillede,id) as qbillede ON qBillede.annonce = tblAnnonce.id
GROUP BY tblAnnonce.id, tblAnnonce.overskrift, tblType.navn ;
Avatar billede bernhof Nybegynder
24. august 2004 - 13:29 #11
Wow! Det virker NÆSTEN! Det eneste problem er, at den returnerer billede1.jpg til annonce 2, hvor den burde returnere billede2.jpg, da dette er hovedbillede. Jeg har prøvet at skrive "ORDER BY hovedbillede DESC, id" i sub-select'en, men det giver samme resultat.
Avatar billede bernhof Nybegynder
25. august 2004 - 16:32 #12
Nogle idéer?
Avatar billede bernhof Nybegynder
26. august 2004 - 00:46 #13
Hvis du virkelig ingen løsning har på problemet, så bare læg endnu et svar. For du skal da point for anstrengelserne indtil videre. (Jeg afviste egentlig bare det andet svar for at vække din opmærksomhed ;)

Jeg må bare oprette et nyt spørgsmål vedr. den query du kom frem til, for så vidt jeg kan se burde den virke efter hensigten. Tror det er en fejl i Access eller sådan noget lignende :)
Avatar billede uffe_kld Nybegynder
26. august 2004 - 01:52 #14
Jeg har desværre ikke nogen løsning, jeg tænkt nærmere over det og tror ikke det kan løses med first-funktionen.
Avatar billede bernhof Nybegynder
26. august 2004 - 12:52 #15
Hm, ok .. Det må jeg se på! Men du skal have tak for hjælpen.
Avatar billede uffe_kld Nybegynder
29. august 2004 - 01:08 #16
Det er lidt af en fusker løsning, med det ser ud til at virke

SELECT tblAnnonce.id, tblAnnonce.overskrift, tblType.navn, antalofid, filnavn
FROM (tblAnnonce INNER JOIN tblType ON tblAnnonce.type = tblType.id) LEFT JOIN 
(SELECT annid, antalofid, filnavn
from (SELECT tblAnnonce.id as annid, Min(IIf([hovedbillede],-1,1)*[tblbillede].[id]) AS krit, Count(tblAnnonce.id) AS AntalOfid
FROM tblAnnonce INNER JOIN tblBillede ON tblAnnonce.id = tblBillede.annonce
GROUP BY tblAnnonce.id) , tblBillede
where abs (krit) = tblBillede.id) as qb
ON qb.annid = tblAnnonce.id
Avatar billede bernhof Nybegynder
29. august 2004 - 18:53 #17
Heheh, den ser ret grum ud ;) Tak for forslaget!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Dyk ned i databasernes verden på et af vores praksisnære Access-kurser

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester