Gå til innhold

MySQL - Problem med unik brukerid og maksverdi


Anbefalte innlegg

Hei, jeg har en database som er bygd opp slik:

 

daily_id  |  daily_bruker  |  daily_verdi  |  daily_type
  1				4			  3401		   HHIT
  2			   8			   2323		   HHIT
  3			   4			   1111		  HHIT
  4				8			  1212		   HHIT

 

Hvilke spørring må jeg kjøre for å hente ut unik daily_bruker med høyest daily_verdi? Alt jeg har prøvd med DISTINCT failer.

 

Eksempel som feiler:

 

SELECT DISTINCT(daily_bruker), daily_id, daily_verdi, daily_type FROM avatar_daily WHERE daily_type = 'HHIT' ORDER BY daily_verdi DESC

Lenke til kommentar
Videoannonse
Annonse
Hei, jeg har en database som er bygd opp slik:

 

daily_id  |  daily_bruker  |  daily_verdi  |  daily_type
  1				4			  3401		   HHIT
  2			   8			   2323		   HHIT
  3			   4			   1111		  HHIT
  4				8			  1212		   HHIT

 

Hvilke spørring må jeg kjøre for å hente ut unik daily_bruker med høyest daily_verdi? Alt jeg har prøvd med DISTINCT failer.

 

Eksempel som feiler:

 

SELECT DISTINCT(daily_bruker), daily_id, daily_verdi, daily_type FROM avatar_daily WHERE daily_type = 'HHIT' ORDER BY daily_verdi DESC

 

select daily_bruker from avatar_daily where daily_verdi = (select max(daily_verdi) from avatar_daily)

Lenke til kommentar

Altså, kanskje jeg er litt uklar her. Greia er at hver bruker kan ha flere oppføringer i databasen, men jeg skal bare hente ut den som er høyest på hver bruker.

 

Så hvis det er tre oppføringer på daily_bruker = 11 skal den av verdiene som er høyest i daily_verdi hentes. Og de skal ORDER BY denne verdien slik at jeg får en oversikt over de høyeste verdiene i tablet.

 

Anyone?

Lenke til kommentar

Takk for hjelpen! Det funket nesten, men fant løsningen selv :)

 

SELECT MAX(daily_verdi) as 'daily_max_verdi', daily_id, daily_type, daily_bruker, daily_verdi
FROM avatar_daily GROUP BY daily_bruker
ORDER BY daily_verdi DESC

 

Lar den stå som uløst litt til. Må teste litt mer frem og tilbake, men ved første øyekast så det veldig lovende ut.

 

Takk!

Lenke til kommentar
Takk for hjelpen! Det funket nesten, men fant løsningen selv :)

 

SELECT MAX(daily_verdi) as 'daily_max_verdi', daily_id, daily_type, daily_bruker, daily_verdi
FROM avatar_daily GROUP BY daily_bruker
ORDER BY daily_verdi DESC

 

Lar den stå som uløst litt til. Må teste litt mer frem og tilbake, men ved første øyekast så det veldig lovende ut.

 

Takk!

Kast et øye til på den. Det du har skrevet er ikke 100% gyldig sql. Du benytter deg av en utvidelse i MySQL. Spørringen kan ikke gi deg forutsigbare resultater.

Gitt tabellen

 

select  * from  avatar_daily order by daily_id

daily_id	daily_bruker	daily_verdi	daily_type
1			   4			   3401			HHIA
2			   8			   2323			HHIB
3			   4			   1111			HHIC
4			   8			   1212			HHID
5			   3			   3402			HHIE
6			   4			   3403			HHIF
7			   4			   3456			HHIG
8			   4			   3456			HHIH
9			   2			   3456			HHIJ

 

får du

 

SELECT MAX(daily_verdi) as 'daily_max_verdi', daily_id, daily_type, daily_bruker, daily_verdi
FROM avatar_daily GROUP BY daily_bruker
ORDER BY daily_verdi DESC

daily_max_verdi	daily_id	daily_type	daily_bruker	daily_verdi
3402			5			   HHIE			3			   3402
2323			2			   HHIB			8			   2323
3403			3			   HHIC			4			   1111

 

Her er vel resultatet ikke som ønsket, f.eks. har bruker 4 en max på 3456 som ikke kommer fram.

 

Du kan skru av denne utvidelsen i MySQL med

 

set SQL_MODE = 'ONLY_FULL_GROUP_BY'

 

Les mer her http://dev.mysql.com/tech-resources/articl...p-by-myths.html

Lenke til kommentar

Hm, interessant lesing.

 

Av rein interesse, hvis jeg skulle fått til denne spørringen uten å måtte endre innstillingene i databasen, åssen hadde den blitt da? Jeg er ikke videre kløpper i MySQL og har lært meg alt ved å prøve og feile (og å spørre om hjelp), men dette er litt ovenfor mitt nivå.

Lenke til kommentar
Hm, interessant lesing.

 

Av rein interesse, hvis jeg skulle fått til denne spørringen uten å måtte endre innstillingene i databasen, åssen hadde den blitt da? Jeg er ikke videre kløpper i MySQL og har lært meg alt ved å prøve og feile (og å spørre om hjelp), men dette er litt ovenfor mitt nivå.

 

hvis du i det heletatt skal kjøre spørringen som den er nå så må du nettopp *ikke* endre innstillingene, ellers får du jo bare en feilmelding. men du får altså ikke nødvendigvis det du spør etter.

 

spørsmålet er hva du egentlig vil ha, du spør jo f.eks. i spørringen etter både max(daily_verdi) *og* daily_verdi for hver bruker. max'en er jo grei, men hva vil du egentlig ha ut som den andre daily_verdien? det kan hverken mysql eller andre skjønne ut fra sql'en.

 

men for meg ser det ut som du bare henter ut litt mer informasjon enn du egentlig vil ha, for du skriver jo innledningsvis «Hvilke spørring må jeg kjøre for å hente ut unik daily_bruker med høyest daily_verdi?»

 

det eneste du trenger da er å fjerne de kolonnene du ikke vil ha fra spørringen du allerede har slik:

 

SELECT MAX(daily_verdi) as 'daily_max_verdi', daily_bruker
FROM avatar_daily GROUP BY daily_bruker
ORDER BY MAX(daily_verdi) DESC

 

her er regelen om at kolonnene enten må dyttes inn i en aggregatfunksjon eller forekomme som grupperingskolonne oppfyllt, og da blir resultatene forutsigbare. Merk aggregatfunksjon i order-by-klausulen også.

 

hvis du også skal ha med andre verdier fra samme rad som max-verdiene må du desverre til med subselects er jeg redd. du kan se hva som skjer her:

 

select * from daily_avatar order by daily_bruker, daily_verdi desc ____________

3456	2	HHIJ -- ok
3402	3	HHIE -- ok
3456	4	HHIG -- du vil ha denne raden også 
3456	4	HHIH -- evt. denne for bruker 4
3403	4	HHIF
3401	4	HHIA
1111	4	HHIC -- ... denne daily_type blir brukt for bruker 4
2323	8	HHIB -- du vil ha denne for bruker 8
1212	8	HHID

 

Spørring A:

 

SELECT MAX(daily_verdi) as 'daily_max_verdi', daily_bruker, daily_type
FROM avatar_daily GROUP BY daily_bruker
ORDER BY max(daily_verdi) DESC ________________

3456	2	HHIJ
3456	4	HHIC -- denne daily_type kommer fra raden med daily_verdi = 1111
3402	3	HHIE
2323	8	HHIB -- ok pga flaks

 

Spørring B:

 

SELECT MAX(daily_verdi) as daily_max_verdi, daily_bruker,
(select daily_type from avatar_daily ad2 
   where ad2.daily_verdi = (select max(daily_verdi) from avatar_daily ad3 where ad3.daily_bruker = ad1.daily_bruker) and ad2.daily_bruker = ad1.daily_bruker LIMIT 1      )
FROM avatar_daily ad1 GROUP BY daily_bruker
ORDER BY MAX(daily_verdi) DESC ____________

3456	4	HHIG -- her har du en daily_type som stemmer med daily_verdi
3456	2	HHIJ
3402	3	HHIE
2323	8	HHIB

 

blir utrolig knotete sql av dette men slik er det nå engang.

Endret av quantum
Lenke til kommentar

alternativt slik:

 

select daily_verdi, daily_bruker, daily_type from avatar_daily ad1
where ad1.daily_verdi = 
(select max(ad2.daily_verdi) from avatar_daily ad2 where ad2.daily_bruker = ad1.daily_bruker)
order by daily_verdi desc

 

som gir

 

3456	4	HHIG
3456	4	HHIH
3456	2	HHIJ
3402	3	HHIE
2323	8	HHIB

 

her ser du også et annet point med max-funksjonen, den returnerer (og du får følgelig gruppert etter) én verdi, mens det faktisk er to rader som har denne verdien for bruker 4.

 

dette virker jo i det heletatt litt snålt, men det blir kanskje lettere å skjønne hvis du tenker på at en aggregatfunksjon generelt ikke nødvendigvis leverer noen verdi som fins i noen rad eller kolonne i tabellen. max() og min() gjør det *tilfeldigvis*, men f.eks. sum() og avg() gjør det *ikke*. forslaget mitt her er derfor ikke noe som virker som en generell omskriving av group-by-spørringer, den fungerer *bare* fordi max() tilfeldigvis leverer en verdi som faktisk fins i en rad/kolonne i tabellen.

Endret av quantum
Lenke til kommentar

Egentlig skal jeg bare ha ut de med HHIT, men det har ingenting å si i eksemplene dere gir.

 

Hm, virker som litt avensert MySQL for meg. Men skal lege grundig igjennom en gang til, krysse fingrene for at jeg forstår og go for it.

 

Jeg skal bare ha ut en daily_verdi som er max for hver daily_bruker. daily_id og daily_type trenger jeg i grunn ikke til resten av scriptet mitt.

 

 

|EDIT| Faktisk, quantum, så prøvde jeg å skrive spørringen sånn, men jeg fikk error, siden jeg ikke ga det første tablet en prefix, og spørringen ble da.

 

SELECT daily_verdi, daily_bruker, daily_type
FROM avatar_daily WHERE daily_verdi = (SELECT MAX(.daily_verdi) FROM avatar_daily WHERE daily_bruker = daily_bruker)
ORDER BY daily_verdi DESC

 

Tror kanskje din løsning er den greieste. Det er i allefall den spørringen jeg forstår 100%

Endret av TheClown
Lenke til kommentar
Jeg skal bare ha ut en daily_verdi som er max for hver daily_bruker. daily_id og daily_type trenger jeg i grunn ikke til resten av scriptet mitt.

 

da kan du bruke group-by spørringen rett fram. Når du har daily_verdi i en aggregatfunksjon (max()) og grupperer etter daily_bruker, og ikke blander inn de andre kolonnene, er alt helt ok.

 

mulig selve problemet blir litt tydeligere hvis du tenker deg at du skulle brukt f.eks. avg() eller sum() istedenfor max(). alle sammen er aggregatfunksjoner som mysql behandler helt likt.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...