1. Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm
    Information ausblenden

TOP TEN einer Tabelle bestimmen ohne spezifische Erweiterungen wie TOP, LIMIT, ROWNUM, FETCH

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von Casutti, 22 Januar 2020.

  1. Casutti

    Casutti Benutzer

    Hallo Ihr Lieben,

    wie kann man die TOP 10 inklusive Rang einer Tabelle bestimmen ohne spezifische Erweiterungen wie LIMIT, TOP, ROWNUM, FETCH o.ä. zu verwenden?
    Z.B für folgende Tabelle:
    Spiel
    ID / Punkte
    3 3
    12 7
    15 2
    17 10
    20 8
    21 12
    31 5
    32 7
    35 6
    37 9
    .. ..
    Mir fallen nur sehr "künstliche Lösungen" wie z.B. folgendes ein:
    select ID, Punkte, 1 AS Rang
    from Spiel
    where Punkte = (Select max(Punkte) from Spiel)
    UNION ALL
    select ID,Punkte, 2 AS Rang
    from Spiel
    where Punkte = (select max(Punkte) from Spiel where Punkte <(select max(Punkte) from Spiel))
    UNION ALL
    ......
    und dann kämen immer mehr dieser verschachtelten Klammern hinzu um den zuvor maximalen auszuschließen
    Das erscheint mir etwas aufgebauscht. Gibts da eine geschickte Lösung wie gesagt ohne Nutzung spezifischer Erweiterungen?

    Über Rückmeldungen würde mich mich sehr freuen!
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Dazu dienen WINDOW-Funktionen - die MySQL in abgehangenen Versionen nicht kann.
     
  3. Casutti

    Casutti Benutzer

    Und wie könnte es ohne diese geschickt klappen?
     
  4. castorp

    castorp Datenbank-Guru

    row_number() oder "FETCH FIRT" sind keine "spezifischen" Erweiterungen sondern seit zig-Jahren Bestandteil des SQL Standards.
    Eine Lösung mit FETCH FIRST (bzw. LIMIT) in MySQL ist mit Sicherheit die effizientes Methode (allerdings kann die nicht damit umgehen wenn Zwei Spieler die gleiche Punktzahl haben). Warum willst Du das nicht verwenden?
     
    Walter gefällt das.
  5. Casutti

    Casutti Benutzer

    Danke für die Rückmeldung! Im Staatsexamen gibt es ab und zu Aufgabenstellungen dieser Art und dann hatte ich mich festgebissen und nach ner geschickten Lösung gesucht. Habe es über MySQL (Programm Xampp ) mal mit rownum versucht, das gibt rownum aber immer als unbekannt aus, daher dachte ich das ist kein Standard ( und wie gesagt oft wird der Befehl explizit ausgeschlossen) und genau wenn es mehrere mit gleicher Punktzahl gibt würde das nicht einfach so gehen. Da müsste ich wahrscheinlich erstmal zählen wieviele Tupel es zu jeder Punktzahl gibt und dann entsprechend das LIMIT größer wählen, oder?
    habe jetzt überlegt ob es ginge das mit with recursive zu machen, da ich ja mit meinen Klammern immer wieder das gleiche mache und immer wieder den letzten Max-Vorgänger ausschließe. Gibt’s da geschickte Möglichkeiten?
     
  6. castorp

    castorp Datenbank-Guru

    rownum ist tatsächlich kein Standard (es ist Oracle spezifisch). Die Window Funktion row_number() hingegen ist Standard (auch wenn MySQL das über Jahrzehnte ignoriert hat).

    Die Lösung über row_number() bzw. dense_rank() ist mit Sicherheit die bessere Wahl - und wenn Du CTEs mit MySQL verwenden kannst, dann hast Du eine aktuelle Version die auch modernes SQL unterstützt und damit auch Window Funktionen (dense_rank())
     
    akretschmer gefällt das.
  7. Casutti

    Casutti Benutzer

    Super! Vielen Dank! Mit dense_rank() funktioniert es auch super mit der Problematik wenn zwei mit gleicher Punktzahl dabei sind.
    Kann man es auch hin bekommen, dass der nächste Platz übersprungen wird wenn es zwei mit gleicher Platzierung gibt?
    Also in obigem Beispiel wären ja die Spieler mit 7 Punkten auf Platz 5, und der Spieler mit 6 Punkten soll dann nicht auf Platz 6 landen, sondern auf Platz 7.
     
  8. castorp

    castorp Datenbank-Guru

    Nimm rank() statt dense_rank()
     
  9. Casutti

    Casutti Benutzer

    1000 Dank!
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden