Ergebnis 1 bis 5 von 5

Thema: Highscore ermittlung

  1. #1
    traxanos ist offline Benutzer
    Registriert seit
    27.05.2008
    Beiträge
    96

    Standard Highscore ermittlung

    Hallo,

    ich habe folgende Tabelle mit folgenden Daten:

    Code:
    CREATE TABLE hs(
      user_id integer NOT NULL,
      rounds integer NOT NULL,
      duration integer NOT NULL,
      CONSTRAINT pkey PRIMARY KEY (user_id, rounds, duration)
    );
    INSERT INTO hs (user_id, rounds, duration) VALUES (1, 4, 2000);
    INSERT INTO hs (user_id, rounds, duration) VALUES (2, 4, 2200);
    INSERT INTO hs (user_id, rounds, duration) VALUES (1, 5, 2100);
    INSERT INTO hs (user_id, rounds, duration) VALUES (3, 6, 2500);
    INSERT INTO hs (user_id, rounds, duration) VALUES (1, 5, 210);
    Nun möchte ich das ganze nach round DESC, duration ASC, user_id ASC sortieren.
    Und nun brauche ich immer den ersten Eintrag pro Pro Benutzer, da ja jeder Benutzer ja nur mit seinem besten Eintrag ins Ranking übernommen werden soll.

  2. #2
    castorp ist offline Erfahrener Benutzer
    Registriert seit
    27.06.2009
    Beiträge
    525

    Standard

    Code:
    select *
    from (
      select user_id,
             rounds,
             duration,
             row_number() over (partition by user_id order by rounds DESC, duration ASC, user_id ASC) as rn
       from hs
    ) t
    where rn = 1
    A SQL query walks into a bar and sees two tables. He walks up to them and says 'Can I join you?'

  3. #3
    akretschmer ist gerade online Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.472

    Standard

    Zitat Zitat von traxanos Beitrag anzeigen
    Hallo,

    ich habe folgende Tabelle mit folgenden Daten:

    Code:
    CREATE TABLE hs(
      user_id integer NOT NULL,
      rounds integer NOT NULL,
      duration integer NOT NULL,
      CONSTRAINT pkey PRIMARY KEY (user_id, rounds, duration)
    );
    INSERT INTO hs (user_id, rounds, duration) VALUES (1, 4, 2000);
    INSERT INTO hs (user_id, rounds, duration) VALUES (2, 4, 2200);
    INSERT INTO hs (user_id, rounds, duration) VALUES (1, 5, 2100);
    INSERT INTO hs (user_id, rounds, duration) VALUES (3, 6, 2500);
    INSERT INTO hs (user_id, rounds, duration) VALUES (1, 5, 210);
    Nun möchte ich das ganze nach round DESC, duration ASC, user_id ASC sortieren.
    Und nun brauche ich immer den ersten Eintrag pro Pro Benutzer, da ja jeder Benutzer ja nur mit seinem besten Eintrag ins Ranking übernommen werden soll.
    Neben der Lösung von castorp geht auch in Versionen vor 8.4:

    Code:
    select distinct on (user_id) user_id, rounds, duration from hs order by user_id, rounds desc, duration asc;
    Ist möglicherweise bei großen Datenmengen schneller als die WINDOWING-Lösung.

    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  4. #4
    traxanos ist offline Benutzer
    Registriert seit
    27.05.2008
    Beiträge
    96

    Standard

    Code:
    select distinct on (user_id) user_id, rounds, duration from hs order by user_id, rounds desc, duration asc;
    das ist falsch, es müsste wenn so aus sehen:

    Code:
    select distinct on (user_id) user_id, rounds, duration from hs order by rounds desc, duration asc, user_id;
    das geht aber ja nicht weil das distinct das order des distinct zuerst erwartet.

    das gleiche gilt für die windowing lösung.

    ergebnis ist bei beiden:

    Code:
    1;5;210;1
    2;4;2200;1
    3;6;2500;1
    korrekt wäre:

    Code:
    3;6;2500;1
     1;5;210;1
    2;4;2200;1

  5. #5
    traxanos ist offline Benutzer
    Registriert seit
    27.05.2008
    Beiträge
    96

    Standard

    wobei man die window funktion noch sortieren kann.

    Code:
    select *
    from (
      select user_id,
             rounds,
             duration,
             row_number() over (partition by user_id order by rounds DESC, duration ASC, user_id ASC) as rn
       from hs
    ) t
    where rn = 1 order by rounds DESC, duration ASC, user_id ASC
    windowing hatte ich zu anfang auch versucht. mein fehler war aber, dass ich dannach auf der user_id distinct habe und dannach nach row_number sortiert habe in 2 subselects. damit hatte ich zwar die richtige sortierung zum user aber nicht die passende werte. aber die variante sieht jetzt sehr gut aus.

Ähnliche Themen

  1. Ermittlung der I/O waits?
    Von antonym im Forum Konfiguration
    Antworten: 0
    Letzter Beitrag: 18.12.2008, 17:18
  2. Ermittlung der Datenbankstruktur
    Von newvil44 im Forum SQL
    Antworten: 13
    Letzter Beitrag: 04.06.2007, 11:59

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Links: Tobias Bauer - IT- und Funkdienstleistungen   -   Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen   -   Funkforum