07. december 2005 - 23:44Der er
14 kommentarer og 1 løsning
Subquery bøvl
Mit indre query giver de ønskede resultater, men det ydre query returnerer kun en del af dem (5 poster). Hvorfor dog ?
SELECT DISCIPLINER.disciplinnavn, RESULTATER.displayscore FROM DISCIPLINER, RESULTATER WHERE DISCIPLINER.disciplinid=RESULTATER.disciplinid AND RESULTATER.personid=50 AND (DISCIPLINER.disciplinid, RESULTATER.score) IN (SELECT DISCIPLINER.disciplinid, MIN(RESULTATER.score) FROM DISCIPLINER, RESULTATER WHERE DISCIPLINER.disciplinid=RESULTATER.disciplinid AND RESULTATER.personid=50 GROUP BY DISCIPLINER.disciplinid) ORDER BY DISCIPLINER.disciplinid, RESULTATER.score;
For det første er det lidt lettere at overskue en så lang query, hvis man lige bryder den lidt op.
SELECT DISCIPLINER.disciplinnavn, RESULTATER.displayscore FROM DISCIPLINER, RESULTATER WHERE DISCIPLINER.disciplinid=RESULTATER.disciplinid AND RESULTATER.personid=50 AND (DISCIPLINER.disciplinid, RESULTATER.score) IN ( SELECT DISCIPLINER.disciplinid, MIN(RESULTATER.score) FROM DISCIPLINER, RESULTATER WHERE DISCIPLINER.disciplinid=RESULTATER.disciplinid AND RESULTATER.personid=50 GROUP BY DISCIPLINER.disciplinid ) ORDER BY DISCIPLINER.disciplinid, RESULTATER.score;
For det andet må du lige give et eksempel på, hvad den inderste giver, hvad den yderste giver, og hvad den yderste skulle have givet. Ellers er det ikke let at hjælpe, da vi andre jo ikke sidder med din database.
(disciplinid er erstattet af disciplinnavn for overskuelighedes skyld. Dette påvirker naturligvis ikke det ydre resultat)
disciplinnavn MIN(RESULTATER.score) 50 m 7.000 60 m 8.000 80 m 10.770 100 m 13.120 200 m 27.220 600 m 109.300 800 m 172.700 1000 m 207.910 60 m hæk (76.2 cm, 6 hække, 11.75 / 7.65 / 10.00) 10.130 60 m hæk (84.0 cm, 5 hække, 13.00 / 8.50 / 13.00) 9.790 4x100 m 48.260 1000 m stafet 133.440 Længdespring (zone) -4.840 Højdespring -1.450 Stangspring -2.700 Kuglestød (3 kg) -10.970 Kuglestød (4 kg) -11.060 Diskoskast (0,75 kg) -26.000 Diskoskast (1 kg) -25.250 Hammerkast (3 kg, 100 cm) -24.150 Spydkast (400 g) -32.930 Spydkast (600 g) -39.980 Boldkast (250 g) -33.360
Der er gode grunde til, at displayscore er en streng, mens score, der kan sorteres på, er et float. Og til at de begge findes. Nogle scores er negative (afhænger af disciplinen) for at voksende sortering kan benyttes på alle discipliner.
Synes godt om
Slettet bruger
12. december 2005 - 08:58#4
Måske det her kan bruges?
SELECT D1.disciplinnavn, R1.displayscore FROM DISCIPLINER as D1, RESULTATER AS R1 WHERE D1.disciplinid=R1.disciplinid AND R1.personid=50 AND R1.score = ( SELECT MIN(R2.score) FROM RESULTATER AS R2 WHERE D1.disciplinid=R2.disciplinid AND R2.personid=50 ) ORDER BY DISCIPLINER.disciplinid, RESULTATER.score;
Det hjalp desværre ikke at give tabellerne et alias, men tak for hjælpen ikke desto mindre.
Synes godt om
Slettet bruger
13. december 2005 - 06:46#6
Kommer den stadig bare med de samme rækker?
Hvilken version af MySQL bruger du?
Og så lige for at sikre mig, at jeg har forstået det korrekt. Du ønsker at lave et udtræk for en person, der lister hans bedste resultat i alle de discipliner, han har deltaget i, korrekt?
Jeg kunne lige prøve at spørge min underviser idag, om han har en ide.
Jo, det var v5. Kan nogen be- eller afkræte, hvorvidt det overhovedet er veldefineret at matche på flere kolonner fra subquerien
Synes godt om
Slettet bruger
14. december 2005 - 05:40#9
Hvis den giver samme resultat, som mit forslag, så må det jo virke, men du matcher jo kun (direkte) på en kolonne nu, eller hvad? Og der var jo også lidt mere i mit forslag, end bare anvendelsen af alias.
Og forskellen på den manualside, jeg linkede til og den tilsvarende manualside for MySQL 5.0 er, at på 5.0-siden står ikke andet end den kode, som jeg gik ud fra i 4.1-maualen. De andre metoder er altså forældede.
Men ellers findes der en metode mere, men det bliver lidt mere langhåret:
SELECT D1.disciplinnavn, R1.displayscore FROM DISCIPLINER AS D1 JOIN RESULTATER as R1 ON D1.disciplinid=R1.disciplinid LEFT JOIN RESULTATER AS R2 ON R1.disciplinid=r2.disciplinid AND R1.score>R2.score AND R2.personid=50 WHERE R1.personid=50 AND R2.score IS NULL
Synes godt om
Slettet bruger
14. december 2005 - 05:42#10
Og ja. Det er med vilje, at jeg brugte et større-end tegn. Det må ikke være et mindre-end, for så får du personens værste score i stedet.
Ang. aliasforslaget, så vil det selvfølgelig ikke virke (efter hensigten) i den form, som du har skitseret det, da der mangler en "group by" i den indre forespørgsel. Er der ellers noget smart ved det?
Querien med et Left Join giver et tomt resultat, men det virker som om, at denne approach kan løse problemet, så nu roder jeg lidt md syntaksen.
I øvrigt: hvordan kan jeg finde ud af, hvilken version af mysql, jeg bruger?
Og angående det, jeg spurgte om tidligere, så er det særdeles veldefineret at matche på flere poster med flere rækker. Det hedder table subquery, og det er så langt, jeg er kommet:-)
Synes godt om
Slettet bruger
15. december 2005 - 07:50#13
Hvis du ser på den side, jeg henviste til fra manualen, vil du se, at der heller ikke er en group by - det burde ikke være nødvendigt, når vi kun selecter en aggregeret funktion, da den så tager for hele tabellen - dog med den udvælgelse der foretages med WHERE-sætningen.
Om den ene er smartere end den anden, kommer nok mest an på, hvad man er vant til at bruge.
Du kan prøve at bruge EXPLAIN på din query, så du kan se mere præcist, hvordan MySQL har tænkt sig at løse opgaven.
SELECT D1.disciplinnavn, R1.displayscore FROM DISCIPLINER as D1, RESULTATER AS R1 WHERE D1.disciplinid=R1.disciplinid AND R1.personid=50 AND R1.score = ( SELECT MIN(R2.score) FROM RESULTATER AS R2 WHERE D1.disciplinid=R2.disciplinid AND R2.personid=50 ) ORDER BY DISCIPLINER.disciplinid, RESULTATER.score;
virker perfekt! Jeg var bare meget skeptisk, fordi der manglede en group by. Nu vil jeg tage mig sammen til at forstå, hvad der egentlig foregår (for at forstå det, og fordi jeg har brug for en udvidelse). Mange tak for hjælpen.
Synes godt om
Slettet bruger
16. december 2005 - 08:40#15
Ok, så vil jeg da lægge et svar
Synes godt om
Ny brugerNybegynder
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.