[MySQL] Plaats in ranglijst (PHP)

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Jeeeroen
  • Registratie: Juni 2004
  • Niet online
Ik heb een MySQL-tabel met daarin id-nummers van leden en het aantal stemmen dat ze hebben gekregen van andere leden. Hoe kan ik nu (met MySQL en eventueel met PHP) op de beste en efficiëntste manier achterhalen op welke positie van de ranglijst één bepaald lid staat? Ik wil dit vermelden op de persoonlijke pagina van leden.

Voorbeeld MySQL-tabel:
IDStemmen
Mark45
Willem23
Gijs87
Bart55

Het aantal rijen in de tabel (leden) is ca. 1.000.

PHP-versie: 4.3.10
MySQL-versie: 4.0.22-standard

Bedankt!

[ Voor 5% gewijzigd door Jeeeroen op 23-02-2005 15:51 ]


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22:43
Ik ga je het antwoord niet kado doen; eerst wat QuickStart vragen: wat heb je zelf al geprobeerd, wat lukte er niet en waarom niet?

Een hint voor de juiste oplossing:
• Als je de hoogste score van iedereen hebt, sta je op plaats 1.
• Als je de op een-na-hoogste score hebt, sta je op plaats 2. Er is dan dus één persoon met een hogere score.
• Als je de op twee-na-hoogste score hebt, sta je op plaats 3. Er zijn dan dus twee personen met een hogere score.
• Als je op de plaats N staat, zijn er dus N-1 personen met een hogere score.

[ Voor 64% gewijzigd door Soultaker op 23-02-2005 15:46 ]


Acties:
  • 0 Henk 'm!

  • Jeeeroen
  • Registratie: Juni 2004
  • Niet online
Wat ik heb geprobeerd: Ik heb in een cronjob die elke minuut draait de MySQL-tabel gesorteerd en vervolgens ieder lid een opeenlopend nummer gegeven, de positie op de ranglijst dus. Dit nummer kan dan geselecteerd worden op de persoonlijke pagina van leden. Het lijkt me dat dit echter op een efficiëntere manier kan.

Ik ga even kijken of ik iets met je tips kan, bedankt in ieder geval.

Acties:
  • 0 Henk 'm!

  • Wolfboy
  • Registratie: Januari 2001
  • Niet online

Wolfboy

ubi dubium ibi libertas

Het eerste dat zo eventjes in me op komt, een count doen van alle mensen met een hogere score dan de persoon.

Is dat misschien een mogelijkheid?

Blog [Stackoverflow] [LinkedIn]


Acties:
  • 0 Henk 'm!

  • Jeeeroen
  • Registratie: Juni 2004
  • Niet online
Zou kunnen Wolfboy, met gedeelde plaatsen wordt dan ook automatisch rekening gehouden, bedenk me net.

Bedankt, ik ga het even proberen!

Acties:
  • 0 Henk 'm!

  • douweh
  • Registratie: Maart 2001
  • Laatst online: 09-10-2024
eerst het aantal stemmen van dat lid eruithalen,
en vervolgens een query doen:
code:
1
$query="SELECT iets FROM tabel WHERE stemmen<stemmenvandatenelid";

Vervolgens t aantal teruggekregen records tellen en de positie van t betreffende lid, is dus 1 meer.

kost je 2 queries per hit, misschien kan t nog makkelijker hoor, maar zou ff niet weten hoe.

Acties:
  • 0 Henk 'm!

  • Jeeeroen
  • Registratie: Juni 2004
  • Niet online
Het aantal stemmen wordt automatisch meegenomen in de query die de informatie voor op de persoonlijke pagina ophaalt, dus dat is geen probleem. Maar het is natuurlijk nog beter als het in één query kan. Ik ben al aan het puzzelen.

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Jeeeroen schreef op woensdag 23 februari 2005 @ 15:53:
Zou kunnen Wolfboy, met gedeelde plaatsen wordt dan ook automatisch rekening gehouden, bedenk me net.
Nee hoor, daar wordt niet automatisch rekening mee gehouden. Hooguit als je van tevoren nog eens groepeert op score, maar dat kan niet zomaar in één query in MySQL. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 19-09 22:18

chem

Reist de wereld rond

Gebruik je MySQL 4.x ?

Klaar voor een nieuwe uitdaging.


Acties:
  • 0 Henk 'm!

  • Jeeeroen
  • Registratie: Juni 2004
  • Niet online
-NMe- schreef op woensdag 23 februari 2005 @ 15:57:
[...]

Nee hoor, daar wordt niet automatisch rekening mee gehouden. Hooguit als je van tevoren nog eens groepeert op score, maar dat kan niet zomaar in één query in MySQL. :)
Wel als je gedeelde plaatsen als volgt rekent, toch?

Pos.NaamStemmen
1.Jan87
Piet87
3.Kees63

Acties:
  • 0 Henk 'm!

  • Jeeeroen
  • Registratie: Juni 2004
  • Niet online
Ja, momenteel 4.0.22-standard.

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22:43
-NMe- schreef op woensdag 23 februari 2005 @ 15:57:
Nee hoor, daar wordt niet automatisch rekening mee gehouden. Hooguit als je van tevoren nog eens groepeert op score, maar dat kan niet zomaar in één query in MySQL. :)
Juist wel! Meestal wil je de plaats delen bij gelijke score, zo dus:
1Soultaker1000 stemmen
2-NMe-500 stemmen
2Jeeeroen500 stemmen
4chem2 stemmen

Als je dan telt hoeveel mensen er meer stemmen hebben dan bijvoorbeeld Jeeeroen kom je op 1 uit, net als voor -NME-, en beiden krijgen zo plaats 2 (terwijl de eerstvolgende wel plaats 4 krijgt en niet plaats 3).

edit:
Ik ben traag vandaag. :+

[ Voor 26% gewijzigd door Soultaker op 23-02-2005 16:04 ]


Acties:
  • 0 Henk 'm!

  • Jeeeroen
  • Registratie: Juni 2004
  • Niet online
Juist, bedankt voor je toelichting Soultaker ;). Gaan we trouwens de goede kant op met de beste oplossing?

Ik heb zo het idee dat de laatste zin niet helemaal klopt...

[ Voor 40% gewijzigd door Jeeeroen op 23-02-2005 16:03 ]


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22:43
Ik doelde op het tellen van het aantal mensen boven je (wat Wolfboy ook zei). Efficiënter zal het niet worden, of je moet de positie in je database opslaan (en dan moet je de positie elke keer dat er gestemd wordt aanpassen). Maar als er een index is op het aantal stemmen, dan kan de database die COUNT-query razendsnel uitvoeren en zou ik eigenlijk niet moelijk gaan doen.

[ Voor 25% gewijzigd door Soultaker op 23-02-2005 16:05 ]


Acties:
  • 0 Henk 'm!

  • Jeeeroen
  • Registratie: Juni 2004
  • Niet online
Hmja, maar of dat efficiënt is... bedankt in ieder geval! Ik laat later vandaag nog wel van me horen wat het is geworden.

Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 19-09 22:18

chem

Reist de wereld rond

Je zou iets kunnen doen als....
[code=mysql]SET @counter = 0[/]
[code=mysql]select (@counter := (@counter + 1)) as counter, username
from votes where id = 4 order by voteCounter asc[/]

zo ff uit de losse pols

Misschien dat een SQL_CALC_FOUND_ROWS erbij nog wat kan uitmaken


eerst ff testen :+

[ Voor 19% gewijzigd door chem op 23-02-2005 16:11 ]

Klaar voor een nieuwe uitdaging.


Acties:
  • 0 Henk 'm!

  • Jeeeroen
  • Registratie: Juni 2004
  • Niet online
Ik ben benieuwd chem ;).

Acties:
  • 0 Henk 'm!

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
code:
1
2
3
SELECT *, (SELECT COUNT(*) FROM Tabel WHERE Stemmen > T.Stemmen) + 1 as Position
FROM Tabel T
ORDER BY Position

[ Voor 9% gewijzigd door P_de_B op 23-02-2005 16:22 . Reden: code tags ]

Oops! Google Chrome could not find www.rijks%20museum.nl


Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

Soultaker schreef op woensdag 23 februari 2005 @ 16:04:
Maar als er een index is op het aantal stemmen, dan kan de database die COUNT-query razendsnel uitvoeren en zou ik eigenlijk niet moelijk gaan doen.
Sterker nog, voor een slimme database is dat instantanous omdat het namelijk per definitie de positie binnen de index is. Ergo hij hoeft niet eens iets te tellen als ie goed optimized :P

* curry684 ziet echter MySQL in de topictitel staan en droomt even verder O-)

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22:43
P_de_B schreef op woensdag 23 februari 2005 @ 16:22:
code:
1
2
3
SELECT *, (SELECT COUNT(*) FROM Tabel WHERE Stemmen > T.Stemmen) + 1 as Position
FROM Tabel T
ORDER BY Position
Dan kun je beter gewoon "SELECT * FROM Tabel ORDER BY Stemmen DESC" doen en zelf de positie erbij verzinnen. (Want ze staan toch gesorteerd op positie.)

Acties:
  • 0 Henk 'm!

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Soultaker schreef op woensdag 23 februari 2005 @ 16:35:
[...]

Dan kun je beter gewoon "SELECT * FROM Tabel ORDER BY Stemmen DESC" doen en zelf de positie erbij verzinnen. (Want ze staan toch gesorteerd op positie.)
Ja, maar ik dacht dat je 1 bepaald lid moest kunnen opzoeken, dus een WHERE clausule toevoegen en direct terugkrijgen op welke positie het betreffende lid staat. De complete query is dan:

code:
1
2
3
4
SELECT *, (SELECT COUNT(*) FROM Tabel WHERE Stemmen > T.Stemmen) + 1 as Position
FROM Tabel T
WHERE lid = 'Peter'
ORDER BY Position


ik had iets duidelijker kunnen zijn.

Oops! Google Chrome could not find www.rijks%20museum.nl


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22:43
Maar die variant was al gesuggereerd, zonder subquery uiteraard, want MySQL 4.0 ondersteunt die niet. ;)

Acties:
  • 0 Henk 'm!

  • Jeeeroen
  • Registratie: Juni 2004
  • Niet online
Edit:
Stomme vraag, er is maar één efficiënte manier genoemd tot nu toe, dus dat is ook automatisch de beste ;)... MySQL 4.0 ondersteunt natuurlijk inderdaad geen subquery's. Ik ben nog steeds benieuwd naar de query van chem!

En een index op de kolom met het aantal stemmen is dus wel aan te raden?

[ Voor 68% gewijzigd door Jeeeroen op 23-02-2005 17:14 ]


Acties:
  • 0 Henk 'm!

  • Wolfboy
  • Registratie: Januari 2001
  • Niet online

Wolfboy

ubi dubium ibi libertas

Jeeeroen schreef op woensdag 23 februari 2005 @ 17:07:
En een index op de kolom met het aantal stemmen is dus wel aan te raden?
In het geval van MySQL, ja ;)

Blog [Stackoverflow] [LinkedIn]


Acties:
  • 0 Henk 'm!

  • Jeeeroen
  • Registratie: Juni 2004
  • Niet online
Wolfboy schreef op woensdag 23 februari 2005 @ 18:45:
[...]
In het geval van MySQL, ja ;)
Ok, dankje. Ik twijfel meestal. Het updaten en inserten kost immers 'meer' tijd als een index is ingesteld...

Acties:
  • 0 Henk 'm!

  • JHS
  • Registratie: Augustus 2003
  • Laatst online: 16-09 16:02

JHS

Splitting the thaum.

Jeeeroen schreef op woensdag 23 februari 2005 @ 18:59:
[...]Ok, dankje. Ik twijfel meestal. Het updaten en inserten kost immers 'meer' tijd als een index is ingesteld...
Het verschilt dan ook of een index handig is, en is (vnl.) afhankelijk van de verhouding write ten opzicht van read. En de enige manier om uit te vinden wát nu precies sneller is, is het testen timen :) .

[ Voor 3% gewijzigd door JHS op 23-02-2005 19:12 ]

DM!


Acties:
  • 0 Henk 'm!

  • Wolfboy
  • Registratie: Januari 2001
  • Niet online

Wolfboy

ubi dubium ibi libertas

Jeeeroen schreef op woensdag 23 februari 2005 @ 17:07:
Stomme vraag, er is maar één efficiënte manier genoemd tot nu toe, dus dat is ook automatisch de beste ;)... MySQL 4.0 ondersteunt natuurlijk inderdaad geen subquery's. Ik ben nog steeds benieuwd naar de query van chem!
Aangezien chem z'n reactie uitblijft geef ik ff een voorbeeldje:
MySQL:
1
2
3
4
SET @counter = 0;
SELECT (@counter := (@counter + 1)) AS counter, t1.username 
FROM votes AS t1, votes AS t2
WHERE t1.Stemmen > t2.Stemmen AND t2.ID = 'Mark';


Efficient? tja :P
Het zal waarschijnlijk wel werken ;)

Blog [Stackoverflow] [LinkedIn]


Acties:
  • 0 Henk 'm!

  • Jeeeroen
  • Registratie: Juni 2004
  • Niet online
Bedankt allemaal, ik weet voorlopig voldoende! Ik hoop dat anderen met dezelfde vraag dit topic kunnen vinden ;).
Pagina: 1