Programmierer da? MYSQL/PHP Problem

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Programmierer da? MYSQL/PHP Problem

      Aloa Wald,

      klar, es ist ggf. nicht das richtige Forum für Programmierfragen, aber von einigen weiß ich ja, dass ihr Programmierer seid.

      Ich habe folgendes Problem.

      Ich habe eine Datenbank, in der User-IDs mitsamt der zugehörigen Gesamtpunktzahl des Users abgespeichert sind. Ich möchte nun zum Besipiel wissen, welchen Ranglistenplatz der User mit der ID 17 hat.

      Momentan sieht die Funktion dazu wie folgt aus:

      Quellcode

      1. function hol_rangpos($id) {
      2. $pos=0;$u=-1;
      3. $sql = "SELECT Id FROM fa_0_user ORDER BY Punkte DESC";
      4. $ergebnis = mysql_query($sql);
      5. while($u!=$id && ($row = mysql_fetch_object($ergebnis))) {
      6. $u = $row->Id;
      7. $pos=$pos+1;
      8. }
      9. return $pos;
      10. }
      Alles anzeigen




      Ergo geht das Skript von Platz 1 alle User durch und zählt dabei die Position hoch.

      Nun haben wir mittlerweile über 1.000 User in drei Ligen - und wollen jetzt richtig Ligen erweitern, also die Userzahl vervielfachen. Nun wird die Funktion natürlich immer langsamer, da sie (zB bei neuregistrierten Usern) immer mehr "falsche" User durchgehen muss, dessen Daten ich gar nicht weiter verarbeite.

      Gibt es also einen php-Befehl, um die Position des Treffers in der Ergebnisliste ausfindig zu machen?

      Also sowas wie

      Quellcode

      1. function hol_rangpos($id) {
      2. $sql = "SELECT Id FROM fa_0_user ORDER BY Punkte DESC LIMIT 1";
      3. $ergebnis = mysql_query($sql);
      4. while($row = mysql_fetch_object($ergebnis)) {
      5. $pos=???; //DER WIEVIELTE WERT IST DAS JETZT GERADE??
      6. }
      7. return $pos;
      8. }

      Herzlichen dank fürs Lesen, ichbin für jeden Tipp dankbar..

      PS: Mit "LIMIT 1" ist mein Hauptproblem, dass es praktisch gar keine Ergebnisliste gibt. Ergo kann ich da auch keine Positionen bestimmen.. Jemand ne Idee?

      Grüße, IP

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von IchMachEinenAufPimp ()

    • ich würde das eher Richtung


      $sql = "Select Punkte from fa_0_user where Id='xy'";
      $seine_Punkte = mysql_query($sql);
      $sql = "Select count(id) from fa_0_user where Punkte>$seine_Punkte";
      $sein_Rang = mysql_query($sql)+1;


      machen (ob der Import von $seine_Punkte in die sql-query geht, weiss ich nicht);

      mit einem Index auf id und einen auf Punkte sollte das sehr schnell gehen.


      Falls du eine ganze Tabelle ausgeben willst, würde ich das prinzipiell so machen:
      1. select alle unterschiedlichen Punkte
      select distinct Punkte from fa_0_user order by punkte desc;
      2. Berechne den Rang für festen Punktsatz
      Select count(id) from fa_0_user where Punkte>diese_Punkte
      Rang = Ergebnis+1
      3. Berechne alle Nutzer mit diesem Ergebnis, also diesem Rang:
      select * from fa_0_user where Punkte=diese_Punkte order by name asc;
      lest Terry Pratchett(RIP) ... und Stephen King, John Katzenbach, Hohlbein, Frank Schätzing, Anne Rice, Andrzej Sapkowski, Anne Bishop, Bernhard Hennen, George R.R. Martin, Markus Heitz, ... (wurde ja langsam Zeit, dass was dazu kommt)

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von Andrean ()

    • Oh hey,

      ich dachte ich hätte hier bereits sowas wie "Ah vielen Dank, grade keine Zeit zum Nachbauen, aber besten Dank schonmal!" geschrieben.. Pustekuchen!

      Also vielen Dank!

      Oben das habe ich verstanden, mit "Select count(id) FROM .. WHERE Punkte>Punktzahl_User" wird ja eigentlich genau das von mir geforderte umgesetzt.

      Werde mir das mal in ein paar Tuts angucken - mit den BEIDEN Indizes das hab ich nämlich noch nicht verstanden. Alle meine Tabellen haben nämlich (momentan) immer nur einen (auto increment) Index, nämlich eben ID. Dass man die Punkte offenbar zusätzlich indizieren kann, ... werde ich jetzt lernen gehen!

      Dankö jedenfalls. Ich meld mich, wenn umgesetzt oder bei Rückfragen - also in jedem Fall!

      Besten Dank nochmal für die Hilfe.

      PS: Zur Zeit war/ist wieder anderes wichtiger - aber das Problem muss (auf Deine Weise) behoben werden. Sobald Zeit mach ich's und meld mich wieder :check:

      edit: Zu Deinen Nachfragen. Nee die Rangliste selbst kann gar nicht mehr ganz ausgelesen werden. Das würde ewig laden und brennende Mausräder verursachen.. Ich nutz da ganz normal "LIMIT 20,20" also mit Variablen damit man durchklicken kann.. Um sich selbst wird die Rangliste je 10 Plätze nach oben und unten ausgegeben, das passt also alles denke ich.

      Es geht nur um die Ranglistenposition, die bei allen Usernamen steht. Also bei Fremd- oder Selbstansicht - das ganz normale "Aktuelle Ranglistenplatzierung: ".hol_rangpos($user_id);
    • die 10 Plätze davor und dahinter könntest du ja auch so basteln:
      1. Punktzahl holen:
      Select Punkte from fa_0_user where Id='xy'
      2. diesen Rang ausrechnen
      Select count(id) from fa_0_user where Punkte>$seine_Punkte

      Rang=Ergebnis+1

      3. ein paar Leute haben dieselbe Punktzahl, ein paar bissel mehr, ein paar bissel weniger:
      die 10 drüber (theoretisch haben ein paar davon den gleichen Rang, wenn sie gleiche Punkte haben) - die müsstest du dann von hinten nach vorn anzeigen:
      select * from fa_0_user where Punkte>diese_Punkte order by Punkte asc, Name asc limit 10;

      die mit gleichem Rang

      select * from fa_0_user where Punkte=diese_Punkte order by Name asc;

      die 10 drunter

      select * from fa_0_user where Punkte<diese_Punkte order by Punkte desc, Name asc limit 10;


      Wenn du es ganz sauber machen willst, kannst du die Mehrfachränge in der Umgebung auch so basteln:

      select Punkte,count(*) as Anzahl from fa_0_user group by punkte order by punkte desc;

      dann weißt du, dass du soundsoviel Leute mit gleicher Punktzahl auf den höheren Rang setzen müsstest.


      Mit Index auf Punkte dürfte das Ganze ein paar Millisekunden dauern, selbst mit einer Million Einträgen.
      lest Terry Pratchett(RIP) ... und Stephen King, John Katzenbach, Hohlbein, Frank Schätzing, Anne Rice, Andrzej Sapkowski, Anne Bishop, Bernhard Hennen, George R.R. Martin, Markus Heitz, ... (wurde ja langsam Zeit, dass was dazu kommt)
    • Neu

      Bist Du btw zufällig beruflicher Programmierer? Wir überlegen nämlich gerade, ob wir die gesamte Cash-Klamotterie extern in Auftrag geben. Ich Hobby-Programmer will das nämlich nicht verantworten, und die anderen Teammitglieder können leider gar nicht programmieren..

      Wenn Du (oder ein Mitleser) sowas kannst, bitte gerne melden. Ich würde dann die Aufgaben präzisieren (prinzipiell: Die gesamte Cash-Abwicklung, bis die User Diamanten im Game besitzen.)

      Grüße soweit

      PS: Bin immernoch nicht zur Rangliste gekommen. Sobald ich das mache, werde ich mich zum eigentlichen Problem rückmelden
    • Neu

      ich programmiere beruflich, hab aber für einen Nebenjob nicht wirklich Zeit. mysql hab ich mir im Rahmen eines Projekts bissel nebenbei angeeignet...
      Aber der mysql-Kram sollte nicht länger als eine halbe Stunde Arbeit kosten, da könnte ich euch unterstützen (php-Kram müsst ihr alleine machen); prinzipiell könnte das so laufen, dass ihr mir die Datenbank per dropbox als myisam-Version (also 3 Dateien pro Tabelle) zukommen lasst, +gewünschte Anfragen (z.B. id->Rang, + Umgebung), und ich ändere die Tabellen so (und geb euch die mysql-Befehle), dass die Anfragen möglichst effektiv beantwortet werden können. (Die Tabellen bei mir haben nicht ein paar Tausend Einträge, sondern einige Millionen, deshalb mach ich mir immer einen Kopp, wie das schnell und effektiv machbar ist - und zwischen normal und schnell oder Anfrage ohne oder mit Index kann gerne mal Faktor 1000 bei der nötigen Zeit liegen)
      lest Terry Pratchett(RIP) ... und Stephen King, John Katzenbach, Hohlbein, Frank Schätzing, Anne Rice, Andrzej Sapkowski, Anne Bishop, Bernhard Hennen, George R.R. Martin, Markus Heitz, ... (wurde ja langsam Zeit, dass was dazu kommt)
    • Neu

      Verstehe, ja ich werde das im Team auf jeden Fall ansprechen und mich bei Dir melden.

      Kennst Du Dich auch mit Cash-Abwicklungen aus? Primär suchen wir jemanden, der das übernehmen kann - denn das ist uns sonst zu unsicher.. Also Kreditkarte, Bankeinzug, PayPal, sowas..

      Andrean schrieb:

      Die Tabellen bei mir haben nicht ein paar Tausend Einträge, sondern einige Millionen, deshalb mach ich mir immer einen Kopp, wie das schnell und effektiv machbar ist - und zwischen normal und schnell oder Anfrage ohne oder mit Index kann gerne mal Faktor 1000 bei der nötigen Zeit liegen
      Jau, daher ja meine Sorgen ;) Ich will es auch von Anfang an richtig machen und nicht irgendwann sagen: "Öhh, jetzt haben wir zu viele User, die Skripte stocken alle.."
    • Neu

      IchMachEinenAufPimp schrieb:

      Kennst Du Dich auch mit Cash-Abwicklungen aus? Primär suchen wir jemanden, der das übernehmen kann - denn das ist uns sonst zu unsicher.. Also Kreditkarte, Bankeinzug, PayPal, sowas..
      lest Terry Pratchett(RIP) ... und Stephen King, John Katzenbach, Hohlbein, Frank Schätzing, Anne Rice, Andrzej Sapkowski, Anne Bishop, Bernhard Hennen, George R.R. Martin, Markus Heitz, ... (wurde ja langsam Zeit, dass was dazu kommt)