Just nu i M3-nätverket
Gå till innehåll
Jonas__B

GROUP BY fungerar inte så bra

Rekommendera Poster

Jonas__B

Jag har en tabell innehållandes lopp som går runtom i sverige (västsverige mestadels, faktiskt) och en tabell innehållandes mina resultat.

 

Jag har försökt att filtrera ut så att jag bara får ut de tiderna jag haft bäst på och gruppera för varje år.

 

Så här skrev jag:

SELECT MIN(`r`.`time`), `e`.`name`, `e`.`length`, `e`.`date` 
`myDate`, YEAR(`e`.`date`) `myYear` FROM `results` `r` 
INNER JOIN `events` `e` ON `e`.`ID`= `r`.`eventID` 
WHERE `r`.`userID`=1 AND `e`.`length`=10 
GROUP BY YEAR(`e`.`date`)
ORDER BY `myYear` ASC, `r`.`time` ASC

 

Vilket blev:

MIN(`r`.`time`) name 			length 	myDate		myYear
00:41:45 	Sylvesterloppet 	10.0 	2004-12-31 	2004
00:42:58 	Göteborg Cross Country 	10.0 	2005-04-09 	2005
00:40:54 	Göteborgs Cross Country 10.0 	2006-04-29 	2006
00:42:00 	Blodomloppet Göteborg 	10.0 	2007-05-30 	2007
00:40:48 	Lerumsloppet 		10.0 	2008-04-26 	2008

 

Vilket först såg rätt ut, men på något sätt så är det fel lopp som står angivna.

Tiderna är årsbästan på 10, fine men som sagt är loppnamnen felaktiga.

 

Så här skall resultatet bli (jag har själv tagit ut dessa rader manuellt)

time 		name 		length 	myDate 	myYear
00:41:45 	Sylvesterloppet 	10.0 	2004-12-31 	2004
00:42:58 	Lerumsloppet 		10.0 	2005-04-23 	2005
00:40:54 	Blodomloppet Göteborg 	10.0 	2006-05-31 	2006
00:42:00 	Sylvesterloppet 	10.0 	2007-12-31 	2007
00:40:48 	Blodomloppet Göteborg 	10.0 	2008-05-28 	2008

 

 

Är något fel i min SQL?

 

[inlägget ändrat 2008-09-23 14:35:32 av Jonas_Bo]

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser
johanafm

GROUP BY [värde] slår samman alla poster med samma [värde], i det här fallet årsdelen av datumet. Det innebär att all övrig information som är unik försvinner (endast ett värde visas). För MIN, SUM etc spelar det ingen roll i och med att de funktionerna endast genererar ett värde, och tillsammans med de använder man därför GROUP BY.

 

Men i och med att name på tävlingarna är olika så kan du inte använda group by som du gör.

 

Således vore det klart enklast att köra två SQL-frågor:

1)

SELECT MIN(results.time) AS mini, YEAR(events.date) AS myYear
FROM results INNER JOIN events ON events.ID = results.eventID
GROUP BY myYear;

 

Gå igenom samtliga årtal från den första frågan och köra den andra frågan mot respektive år. Antag att du sätter @mini och @myYear till respektive värde i ditt result set från fråga 1.

 

2)

SELECT results.time, name, length, events.date
FROM results INNER JOIN events ON events.ID = eventID
WHERE YEAR(events.date) = @year AND results.time = @mini;

 

 

Vill du tvunget ha ut allting med en fråga så är det enklaste jag kan komma på:

SELECT results.time, name, length, events.date, YEAR(events.date)
FROM results INNER JOIN events ON events.ID = eventID
WHERE results.time IN
(SELECT mini
FROM 
  (SELECT MIN(results.time) AS mini, YEAR(events.date) AS myYear
  FROM results INNER JOIN events ON events.ID = eventID
  GROUP BY myYear) AS tmp);

 

Den allra sista biten "AS tmp" måste vara med. En härledd tabell (derived table) måste alltid tilldelas ett alias. Jag valde "tmp".

 

För läsbarhetens skull rekommenderar jag dig att skippa backticks ` annat än när de verkligen behövs. Dvs, använd de endast när du döpt tabeller eller fält till reserverade ord. Själv skulle jag försöka undvika dylika ord helt och hållet när jag skapar databasen om det är möjligt (exempelvis "edate", "eventdate" eller "event_date" i stället för "date").

 

[inlägget ändrat 2008-12-02 21:37:13 av johanafm]

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser

Skapa ett konto eller logga in för att kommentera

Du måste vara medlem för att kunna kommentera

Skapa ett konto

Skapa ett nytt konto på vårt forum. Det är lätt!

Registrera ett nytt konto

Logga in

Redan medlem? Logga in här.

Logga in nu



×
×
  • Skapa nytt...