[MySQL] Tabel met punten/spelers -> ranglijst

Pagina: 1
Acties:

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Ik heb een tabel met spelers met daarin onder andere rang en punten. Nu kan ik met een "order by punten desc" wel sorteren op punten en dan in PHP met een update query de rangen in de DB zetten, maar kan dit niet met een enkele query?

Voorbeeld:
Voor:
A, 10 punten, NULL
B, 5 punten, NULL
C, 12 punten, NULL

Na:
A, 10, 2
B, 5, 3
C, 12, 1

  • _-= Erikje =-_
  • Registratie: Maart 2000
  • Laatst online: 06-07 14:29
gewoon helemaal niet doen? die rang is iets afhankelijks van de punten en kun je dus in je je script berekenen. Net zoals dat je geen leeftijd in een database opslaat maar een geboortedatum...

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Maar als ik dan de rang van een speler nodig heb moet ik de hele tabel sorteren. En de rang van een speler is vaak nodig zonder dat de hele ranglijst nodig is.

Verwijderd

OlafvdSpek schreef op 02 januari 2003 @ 20:52:
Maar als ik dan de rang van een speler nodig heb moet ik de hele tabel sorteren. En de rang van een speler is vaak nodig zonder dat de hele ranglijst nodig is.
Je weet toch hoeveel punten een bepaalde rang is, dan haal je dus het aantal punten van die speler op, en bekijk je aan de hand van dat aantal punten wat de rang is. Zo kun je de rangen ook makkelijker aanpassen.

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Nee, het gaat niet op die manier. Rang is gewoon 1, 2, 3, 4, 5, ... gebaseerd op de positie in de lijst (het relatieve aantal punten), niet gebaseerd op het absolute aantal punten.

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

[nohtml]
OlafvdSpek schreef op 02 January 2003 @ 20:40:
maar kan dit niet met een enkele query?
In een database met subqueries (mysql dus niet) kan dat in 1 query ja... Tenminste, als je in 1 query de rang van de persoon kan krijgen en dat is niet altijd even makkelijk :)

Verder heeft het opslaan van de rang bij de punten opzich wel nut, maar alleen als je tabel echt vaak benadert wordt en niet al te vaak gewijzigd.

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 26-08 16:18
Er is nog steeds niemand die een betere oplossing gevonden heeft om het verlies van subqueries te vervangen, behalve wat gedoe met joins dan. Of is er toch al iemand die iets handigs gevonden heeft?

  • simon
  • Registratie: Maart 2002
  • Laatst online: 23:15
djluc schreef op 03 januari 2003 @ 21:08:
Er is nog steeds niemand die een betere oplossing gevonden heeft om het verlies van subqueries te vervangen, behalve wat gedoe met joins dan. Of is er toch al iemand die iets handigs gevonden heeft?
Join's zullen dit niet echt handig oplossen denk ik.. Als het echt 'zo nodig' is zou je kunnen wachten op versie 4 + (want daar zit het geloof ik wel in.) En als het echt zo nodig is waarom niet een andere DBMS gebruiken...

|>


  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 26-08 16:18
Als je bijv. heel uitgebreide stats wilt opslaan heb je nodig voor iedere hit:
-pagina id
-bezoekersid
-browserid
-flash id en ga zo nog maar even door...
Voor alle gegevens zou je dus een query uit kunnen voeren, das niet echt gaaf, zeker niet omdat dit bij iedere hit, leess heel erg vaak dus, gebeurt.

  • Goodielover
  • Registratie: November 2001
  • Laatst online: 18-08 11:34

Goodielover

Only The Best is Good Enough.

Het kan gewoon met een join en een group by.
Je telt in de group by het aantal spelers met een grotere score en daarmee heb je de rangorde. (nog wel even 1 bij optellen)

Standaard probleem trouwens. Jammer dat de search je niet kon helpen.

[ Voor 1% gewijzigd door Goodielover op 03-01-2003 23:01 . Reden: typo ]


  • Vigory
  • Registratie: November 2000
  • Laatst online: 15-04 10:26
Misschien heb je hier wat aan:
code:
1
2
3
4
SELECT t1.Naam as naam, t1.score as score, (Count(t2.score)+1) AS positie 
FROM gebruiker AS t1 LEFT JOIN gebruiker AS t2 ON t1.score < t2.score 
GROUP BY t1.naam, t1.score 
ORDER BY t1.score DESC, t1.naam

[ Voor 3% gewijzigd door Vigory op 03-01-2003 23:11 ]


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Goodielover schreef op 03 januari 2003 @ 23:00:
Het kan gewoon met een join en een group by.
Je telt in de group by het aantal spelers met een grotere score en daarmee heb je de rangorde. (nog wel even 1 bij optellen)
Als ik 10^4 miljoen spelers heb krijg ik dus een tijdelijk resultaat van 10^8 records. Ik had het graag iets efficienter gezien.
Standaard probleem trouwens. Jammer dat de search je niet kon helpen.
Als je weet waarnaar je zoekt is het makkelijk te vinden. Met rang kon ik niks vinden.

  • robjanssen
  • Registratie: September 2001
  • Laatst online: 02-08 16:10

robjanssen

Software Developer

code:
1
2
3
4
5
SELECT COUNT(*) + 1
FROM Speler
WHERE Score > (SELECT Score
                          FROM Speler
                          WHERE Speler_ID = ?)


MSSQL ondersteunt trouwens geen SubQuery's
Dus dan moet het worden:

code:
1
2
3
4
SELECT COUNT(*) + 1
FROM Speler S1, Speler S2
WHERE S1.Score > S2.Score
AND S2.Speler_ID = 4

[ Voor 38% gewijzigd door robjanssen op 04-01-2003 17:39 ]


  • Goodielover
  • Registratie: November 2001
  • Laatst online: 18-08 11:34

Goodielover

Only The Best is Good Enough.

OlafvdSpek schreef op 04 januari 2003 @ 12:51:
[...]
Als ik 10^4 miljoen spelers heb krijg ik dus een tijdelijk resultaat van 10^8 records. Ik had het graag iets efficienter gezien.
[...]
Net best als je dbms de query zo zou oplossen.
Ik zie dat mijn oplossin in woorden al door anderen is uitgewerkt. Gebruik een van die oplossingen maar.

[ Voor 10% gewijzigd door Goodielover op 04-01-2003 18:01 ]


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Goodielover schreef op 04 January 2003 @ 18:01:
Net best als je dbms de query zo zou oplossen.
Ik zie dat mijn oplossin in woorden al door anderen is uitgewerkt. Gebruik een van die oplossingen maar.
Ik ga wel uit van een query om de rangen van alle splers op te halen.
Voor 10^4 spelers moet dan gekeken worden hoeveel spelers er meer punten hebben. Volgens mij kost dat per speler toch weer 1/2 * 10^4 record reads. Of niet?

  • Goodielover
  • Registratie: November 2001
  • Laatst online: 18-08 11:34

Goodielover

Only The Best is Good Enough.

Indexje op de punten doet wonderen volgens mij. Bovendien is de waarde van een lijst van 10000 spelers te betwijfelen.
Als je ze in een lijst wil laten zien, is een ORDER BY voldoende. Het rangnummertje stel je dan tijdens de presentatie vast.
Als je het van een kleine groep mensen wilt weten, is mijn query echt goed te doen.

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Goodielover schreef op 06 januari 2003 @ 17:22:
Indexje op de punten doet wonderen volgens mij. Bovendien is de waarde van een lijst van 10000 spelers te betwijfelen.
Als je ze in een lijst wil laten zien, is een ORDER BY voldoende. Het rangnummertje stel je dan tijdens de presentatie vast.
Als je het van een kleine groep mensen wilt weten, is mijn query echt goed te doen.
http://westwood.ea.com/we...redalert2/rankindex.html: 16000+ spelers.
Ik weet niet of MySQL slim genoeg is om zo'n count en group by direct via een index op te lossen.

  • robjanssen
  • Registratie: September 2001
  • Laatst online: 02-08 16:10

robjanssen

Software Developer

Maar als je toch een order by gebruikt dan krijg je met je Recordset toch al de rangen terug. Het eerste record heeft de hoogste rang en het laatste record de laagste rang.
Countertje erbij gebruiken en voila.

  • Goodielover
  • Registratie: November 2001
  • Laatst online: 18-08 11:34

Goodielover

Only The Best is Good Enough.

Heeft de index geen pseudo column met een rangnummer? zou mooi zijn in dit geval

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
robjanssen schreef op 06 January 2003 @ 19:17:
Maar als je toch een order by gebruikt dan krijg je met je Recordset toch al de rangen terug. Het eerste record heeft de hoogste rang en het laatste record de laagste rang.
Countertje erbij gebruiken en voila.
Dan wel. Maar het komt heel vaak voor dat ik van slechts een speler de rang nodig heb.
Of dat ik bijvoorbeeld de rangen 100-125 wil laten zien. En dan is het wel zo handig als ik dat via where kan doen.

  • Goodielover
  • Registratie: November 2001
  • Laatst online: 18-08 11:34

Goodielover

Only The Best is Good Enough.

Dat doe je dan dus niet via een where maar via een having clause

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Dat snap ik. Maar having and where zijn niet equivalent en having kost (meestal) meer tijd dan where.

  • Goodielover
  • Registratie: November 2001
  • Laatst online: 18-08 11:34

Goodielover

Only The Best is Good Enough.

Maar het kan niet met een where omdat je een conditie wilt leggen op een count. en die MOET in de HAVING
Pagina: 1