Kom ihåg mig?
Home Menu

Menu


Problem med SQL-fråga

 
Ämnesverktyg Visningsalternativ
Oläst 2010-11-09, 17:53 #1
Roberts avatar
Robert Robert är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Jan 2004
Inlägg: 2 103
Robert Robert är inte uppkopplad
Klarade millennium-buggen
Roberts avatar
 
Reg.datum: Jan 2004
Inlägg: 2 103
Standard Problem med SQL-fråga

Hej på er,

Sitter fast i SQL-träsket med en fråga jag inte får till...
Nedan har jag två (fejkade) tabeller, en för användare och en för adresser. En användare kan ha flera adresser där ett datum bestämmer vilken adress som är den senaste (aktuella).

Hur gör jag för att selektera ut samtliga users och joina in endast den senaste adressen för varje user? Det som ställer till det för mig är att jag vill kunna selekta ut alla kolumner från adress-tabellen (svårt att göra en group by med andra ord)
Kod:
Users:
UserId  Name
================
1        Nisse
2        Kalle
3        Gustav

Adress:
========================
AdressId UserId  Street   Date
1           1         Road1   2008-11-01
2           2         Road2   2008-11-01
3           3         Road3   2008-11-01
4           3         Road4   2009-11-01
5           3         Road5   2010-05-01

Senast redigerad av Robert den 2010-11-09 klockan 17:56
Robert är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-11-09, 18:09 #2
Magnus_A Magnus_A är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: May 2006
Inlägg: 2 604
Magnus_A Magnus_A är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: May 2006
Inlägg: 2 604
Pröva med att ha en sammansatt index med autoincrement som bygger på båda kolumnerna AdressId och UserId i adress-tabellen

Då kommer tabellen att se ut så här:
Adress:
========================
Kod:
AdressId UserId  Kombo_Autoincrement Street   Date
1           1               1                             Road1   2008-11-01
2           2               1                              Road2   2008-11-01
3           3               1                              Road3   2008-11-01
4           3               2                             Road4   2009-11-01
5           3               3                             Road5   2010-05-01

Senast redigerad av Magnus_A den 2010-11-09 klockan 18:14 Anledning: Nu såg det bättre ut
Magnus_A är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-11-09, 19:45 #3
Roberts avatar
Robert Robert är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Jan 2004
Inlägg: 2 103
Robert Robert är inte uppkopplad
Klarade millennium-buggen
Roberts avatar
 
Reg.datum: Jan 2004
Inlägg: 2 103
Hmmm, jag har tyvär bara möjlighet att skriva frågor, inte ändra i databasstrukturen. Det var väl det ditt förslag gick ut på?
Robert är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-11-09, 19:55 #4
dAEks avatar
dAEk dAEk är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Dec 2006
Inlägg: 678
dAEk dAEk är inte uppkopplad
Mycket flitig postare
dAEks avatar
 
Reg.datum: Dec 2006
Inlägg: 678
Kod:
select 
	u.*, 
	a.*
from 
	Users u
	join [Address] a on a.UserId = u.UserId and a.AddressId = (select top 1 AddressId from [Address] where UserId = u.UserId order by [Date] desc)
Koden är otestad så det kanske inte funkar eller går ohyggligt långsamt men jag tycker att det ser ok ut.
dAEk är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-11-09, 20:35 #5
Roberts avatar
Robert Robert är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Jan 2004
Inlägg: 2 103
Robert Robert är inte uppkopplad
Klarade millennium-buggen
Roberts avatar
 
Reg.datum: Jan 2004
Inlägg: 2 103
Citat:
Ursprungligen postat av dAEk Visa inlägg
Koden är otestad så det kanske inte funkar eller går ohyggligt långsamt men jag tycker att det ser ok ut.
Tackar, det verkar fungera rakt av faktiskt, jag har lite dåligt med testdata för att kontrollera det. Men jag ser iaf din idé och det verkar vara så man ska gå till väga!
Robert är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-11-11, 12:30 #6
martines avatar
martine martine är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Mar 2005
Inlägg: 767
martine martine är inte uppkopplad
Mycket flitig postare
martines avatar
 
Reg.datum: Mar 2005
Inlägg: 767
Citat:
Ursprungligen postat av dAEk Visa inlägg
Koden är otestad så det kanske inte funkar eller går ohyggligt långsamt men jag tycker att det ser ok ut.
Man kan ju tillägga att subqueries kan bli enormt långsamma.

Varför man inte skulle använda en join med group by här har jag svårt att förstå.
martine är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-11-11, 21:23 #7
dAEks avatar
dAEk dAEk är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Dec 2006
Inlägg: 678
dAEk dAEk är inte uppkopplad
Mycket flitig postare
dAEks avatar
 
Reg.datum: Dec 2006
Inlägg: 678
Uppdaterat 2010-11-12:

Med 1 miljon rader i båda tabellerna tog frågan ca 6 sekunder (~19 allt som allt, inkl. att returnera alla rader) att köra på min 5 år gamla burk.

Körde sedan frågan genom query tuning analysern och det visade sig att jag inte hade bra index. Med ett nytt index som innehåller både UserId och Date körs frågan omedelbums. Det som tar tid är att returnera raderna (~14 sek).

Hur som helst: Sql är inte mitt starkaste område så andra lösningar är fortfarande intressanta.

Hur skulle du skriva frågan?

Senast redigerad av dAEk den 2010-11-12 klockan 21:05
dAEk är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-11-11, 22:03 #8
Magnus_A Magnus_A är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: May 2006
Inlägg: 2 604
Magnus_A Magnus_A är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: May 2006
Inlägg: 2 604
När man använder group by är det svårt att styra vilken rad i gruppen som väljs ut. Enligt mina erfarenheter är det den första raden, och man skulle kunna styra det genom att sortera tabellen i förväg. Men det är odokumenterat och jag skulle inte lite på det. Subquery är nog vägen att gå här, om man inte kan göra tabellen på ett bättre sätt.
Magnus_A är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-11-26, 20:39 #9
dAEks avatar
dAEk dAEk är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Dec 2006
Inlägg: 678
dAEk dAEk är inte uppkopplad
Mycket flitig postare
dAEks avatar
 
Reg.datum: Dec 2006
Inlägg: 678
Citat:
Ursprungligen postat av martine Visa inlägg
Man kan ju tillägga att subqueries kan bli enormt långsamma.

Varför man inte skulle använda en join med group by här har jag svårt att förstå.
Två veckor senare väntar vi fortfarande på en bättre lösning.
dAEk är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-11-26, 20:58 #10
tartareandesire tartareandesire är inte uppkopplad
Supermoderator
 
Reg.datum: Jan 2004
Inlägg: 11 585
tartareandesire tartareandesire är inte uppkopplad
Supermoderator
 
Reg.datum: Jan 2004
Inlägg: 11 585
Citat:
Ursprungligen postat av Magnus_A Visa inlägg
När man använder group by är det svårt att styra vilken rad i gruppen som väljs ut. Enligt mina erfarenheter är det den första raden, och man skulle kunna styra det genom att sortera tabellen i förväg. Men det är odokumenterat och jag skulle inte lite på det. Subquery är nog vägen att gå här, om man inte kan göra tabellen på ett bättre sätt.
Såvida man inte byter databas så fungerar det alldeles utmärkt men som du säger så är det ingenting som finns dokumenterat. Jag ser heller ingen annan utväg än att göra en subquery men att då också se till att ha indexerat ordentligt. Det optimala hade varit att flagga aktuell adress eller helt enkelt bara arkivera gamla adresser för att få en betydligt mindre tabell att arbeta med (om den nu är alltför stor) men nu finns uppenbarligen inte det alternativet tillgängligt av någon anledning.

Om ni verkligen inte har möjlighet att ändra databasen på något vis så skulle en extrem alternativ lösning vara att spara varje användare med nuvarande adress i en fil.
__________________
Full-stack developer, free for smaller assignments

Senast redigerad av tartareandesire den 2010-11-26 klockan 21:27
tartareandesire är inte uppkopplad   Svara med citatSvara med citat
Svara


Aktiva användare som för närvarande tittar på det här ämnet: 1 (0 medlemmar och 1 gäster)
 

Regler för att posta
Du får inte posta nya ämnen
Du får inte posta svar
Du får inte posta bifogade filer
Du får inte redigera dina inlägg

BB-kod är
Smilies är
[IMG]-kod är
HTML-kod är av

Forumhopp


Alla tider är GMT +2. Klockan är nu 20:44.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson
 
Copyright © 2017