webForumDet fria alternativet

Ta reda på position baserat på röster

Databaser & SQLur Databashanterare & SQL

9 svar · 894 visningar · startad av xcalibrate

xcalibrateMedlem sedan aug. 2002136 inlägg
#1

Hej!

Jag har en tabell Songs som ser ut ungefär såhär:
ID Artist Title
1 Basshunter Boten Anna
2 The Ark Prayer for the Weekend

Sedan har jag en tabell Votes som ser ut ungefär såhär:
ID Song Strength
1 1 5
1 2 4

Strength är alltså styrkan på rösten mellan 1-5.

Såhär gör jag för att hämta alla låtar med betyg.

select s.title, avg(v.strength) as betyg
from songs s
left join votes v
on s.id = v.song_id
group by s.id

Detta fungerar bra, men hur gör jag om jag vill hämta låt säga låt med ID 1 och ta reda på vilken position/plats den ligger på totalt?

Jag vill alltså få fram ett nummer som är positionen för låten beorende på röster.

Tack på förhand!

Denna länk kanske kan vara till hjälp

LarsGMedlem sedan dec. 200012 464 inlägg
#2
select count(*) + 1 as place
  from 
      (select song_id
         from votes
        group by song_id
       having avg(strength) > 
           (select avg(strength) 
              from votes
             where song_id = 1)) dt
xcalibrateMedlem sedan aug. 2002136 inlägg
#3

Tack, det fungerade jättebra förutom vid ett villkor, om en låt inte har några röster (dvs. 0 i betyg). Alla som har 0 i betyg nu (inga röster) får place 1. Dem borde istället få en position efter alla som har röster.

Hur löser jag detta på en bra sätt?

LarsGMedlem sedan dec. 200012 464 inlägg
#4
select count(*) + 1 as place
  from 
      (select song_id
         from votes
        group by song_id
       having avg(strength) > 
          coalesce((select avg(strength) 
              from votes
             where song_id = 1),0) dt
xcalibrateMedlem sedan aug. 2002136 inlägg
#5

Det fungerade kanon!

Nu inser jag dock att det är ganska många med samma betyg och får därför samma place, och därefter får även dom som ligger efter konstig place te.x:

1. låt1 <- betyg 5.0
1. låt2 <- betyg 5.0
1. låt3 <- betyg 5.0
4. låt4 <- betyg 2.0 <- den borde ju få rank 2 eller att det blir 1, 2, 3, 4 istället för 1, 1, 1, 4

Tack på förhand!

@ndersMedlem sedan juni 200032 969 inlägg
#6

Vad tycker du är konstigt? Det är väl självklart att en låt som har tre ovanför sig ligger på fjärde plats, och inte andra?

Ditt resultat är riktigt - det är på detta sätt resultatlistor (nu menar jag inte bara i databashänseende, utan i verkliga livet) normalt sett ser ut.

xcalibrateMedlem sedan aug. 2002136 inlägg
#7

Problemet uppstår av någon anledning när jag vill hämta röster från ett specifikt land från artist. Se nedan hur jag gjort nu:

SELECT COUNT(*) + 1 AS rank
FROM (SELECT v.song_id
	FROM votes v
	INNER JOIN songs s
	ON v.song_id = s.id
	INNER JOIN artists a
	ON s.artist_id = a.id
	WHERE a.country = "se"
	GROUP BY v.song_id
	HAVING AVG(strength) > (SELECT AVG(strength) FROM votes WHERE song_id = 1)) dt

Det blir inga fel men jag får såhär:

1. låt1 -> betyg 5.0
2. låt2 -> betyg 4.0
4. låt3 -> betyg 3.5 <- här borde det väl vara 3.
4. låt3 -> betyg 3.5 <- här borde det väl vara 3.
6. låt4 -> betyg 3.0 <- och här borde det vara 4

LarsGMedlem sedan dec. 200012 464 inlägg
#8

Du måste ta med country när du räknar ut avg i subselecten.

xcalibrateMedlem sedan aug. 2002136 inlägg
#9
SELECT COUNT(*) + 1 AS rank
FROM (SELECT v.song_id
	FROM ' . TABLE_VOTES . ' v
	GROUP BY v.song_id
	HAVING AVG(strength) > (SELECT AVG(v.strength) FROM ' . TABLE_VOTES . ' v INNER JOIN ' . TABLE_SONGS . ' s ON v.song_id = s.id INNER JOIN ' . TABLE_ARTISTS . ' a ON s.artist_id = a.id WHERE v.song_id = ' . $song['id'] . ' AND a.country = "se")) dt

När jag gjorde så blev det:
1. låt1 -> betyg 5.0
5. låt2 -> betyg 4.0
12. låt3 -> betyg 3.5
12. låt3 -> betyg 3.5
15. låt4 -> betyg 3.0

Det hjälpte heller inte om jag behöll a.country = "se" innan subselected också :/

Jag kanske missförstår dig?

xcalibrateMedlem sedan aug. 2002136 inlägg
#10

Tänker jag galet?

141 ms totalt · 3 externa anrop · v20260731065814-full.c74b5be1
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
138 ms — hämta tråd, inlägg och bilagor (db)