ranking-funktion

DerBenny

Grünschnabel
hi, komme hier an einer Stelle nicht weiter, vielleicht weiß von euch jemand rat

es geht darum, eine Menge von "spielern" mitsamt ihrem "punktestand" sowie - und hier wirds schwierig - ihrem "rang" (also der anzahl der besseren spieler + 1) mittels eines Querys auszulesen

mein Ansatz (auf das Wesentliche reduziert):

Code:
SELECT player, score, (
        SELECT COUNT(*)+1
        FROM (
            SELECT 1
            FROM players
            WHERE score>plr.score
        ) AS better
    ) AS rank
FROM players AS plr
WHERE player IN (....)

Problem: in der inneren WHERE-Klausel kennt er das äußere score nicht, jedenfalls nicht auf diese Weise. Gibt es da evt. eine Möglichkeit, das nach innen "durchzuschleifen" bzw. lässt sich die Problemstellung evt. anders lösen (mit nem JOIN oder so)?

Grüße, Benny

PS: es muss ohne Stored Procedures gehen
 
Läßt sich der Rang eventuell aus einer Sortierung nach dem Score ableiten? Oralce bietet hierfür die rownum as pseudo colloumn, keine Ahnung ob andere DBMS sowas auch haben.

Eventuell kannst Du den Rank auch außerhalb per Zähler (bei entsprechnder Sortierung) nachbilden..

Gruß
 
Problem ist, dass es sich um eine recht große Tabelle (~1MB) handelt und die "spieler" nur punktuell ausgewählt werden... somit wäre ein Durchnummerieren m.E. zu performancelastig, da es das komplette Auslesen der Tabelle erfordert
 
Welches DBMS nutzt du?

Ansonsten gibt's z.B. unter Oracle die Möglichkeit mit #define Austauschvariablen festzulegen, die dann im Select verwendet werden können.

Oder du machst einen PL/SQL-Block.

Oder du schreibst für den inneren Select eine Funktion (stored procedure, oder wie auch immer die in deinem DBMS heißen), der du vom äußeren die score mitgibst.
 
nutze MySql, habe gerade festgestellt, dass Stored Procedures doch möglich sind, Werd mir das mal anschauen, danke soweit
 
Hallo,

die Query kannst du doch einfacher schreiben:

SQL:
SELECT player, score, (
     SELECT COUNT(*)+1
       FROM players
      WHERE score>plr.score
 ) AS rank
  FROM players AS plr
  order by score desc
  limit 20


Ich habs mal mit 10.000 Einträgen probiert.
Wenn deine Tabelle zu gross werden sollte, kannst du sie ja eventuell splitten in die "Stammdaten" der Player und die Punktzahlen etc.

Markus
 
habs letztendlich so gemacht, wie Markus es vorgeschlagen hat. Seltsamerweise spuckte mein phpmyadmin bei dieser Anfrage immer einen Error bei "SHOW KEYS FROM" aus, im eigentlichen PHP script funktionierts aber :confused:

die eingangs komplizierte Abfrage resultierte übrigens daraus, dass der score sich ursprünglich aus einer Aggregation ergab und COUNT(*) in diesem Fall ja leider nicht die gewünschte Anzahl der Gruppen, sondern die Anzahl der Records pro Gruppe liefert...

naja, auf jeden Fall Problem gelöst, thx

Grüße
Benny
 
da in der Diskussion auch auf Oracle Bezug genommen wurde, wollte ich nur noch ergänzen, dass es dort seit 8.1.5 die analytische Funktion rank gibt, die man in solchen Fällen verwenden könnte. Der Vorteil der Analytics ist, dass man die Daten nur einmal lesen muss und sich den Self-Join sparen kann.

Gruß

MP
 
Zurück