globe: SUBQUERY & LIMIT

Beitrag lesen

n'abend,

Nun möchte ich allerdings für jeden Mitspieler die Punkte der letzten 3 Runden, die dieser mitgespielt hat, zusammenaddiert anzeigen.

Das ist mithilfe unbenannter Views kein Problem. Du würdest in einem unbekannten View die drei höchsten Spiel-nummern auswählen, das dann gegen deine Spielstand-Tabelle JOINen (wodurch alle Datensätze mit einer anderen Spiel-ID rausgeworfen werden würden) und darauf dann die Summe bilden.

Also nicht die 3 letzten Runden allgemein (7,6,5), sondern für jeden einzelnen Mitspieler (Bernd -> 7,6,5, Klaus 7,5,3, Stefan 3,2,1).

Das verkompliziert die Sache allerdings gewalttätigst. Diese unbenannten Views werden VOR dem JOIN ausgeführt, was bedeutet, dass wir da nicht korrelierend drauf agieren können. Da fällt mir auf Anhieb nur eine sehr widerliche Abfrage ein, wenn man nicht mit temporären Tabellen arbeiten möchte oder kann.

Wir brauchen das letzte Spiel für jeden Benutzer:

SELECT s.name, MAX(s.spiel)  
  FROM spiele_tabelle s  
 GROUP BY name;

Wir brauchen das vorletzte Spiel für jeden Benutzer:

SELECT s.name, MAX(s.spiel)  
  FROM spiele_tabelle s  
 WHERE s.spiel < (  
       SELECT MAX(s1.spiel)  
         FROM spiele_tabelle s1  
        WHERE s1.name = s.name  
       )  
 GROUP BY name;

Wir brauchen das vorvorletzte Spiel für jeden Benutzer:

SELECT s.name, MAX(s.spiel)  
  FROM spiele_tabelle s  
 WHERE s.spiel < (  
       SELECT MAX(s1.spiel)  
         FROM spiele_tabelle s1  
        WHERE s1.name = s.name  
          AND s1.spiel < (  
              SELECT MAX(s2.spiel)  
                FROM spiele_tabelle s2  
               WHERE s2.name = s.name  
              )  
       )  
 GROUP BY name;

Das sind drei getrennte Abfragen, die dummerweise auch noch das gleiche immer wieder machen. Wie die Redundanz in den Abfragen aufgelöst werden könnte, entzieht sich gerade meiner Vorstellungskraft. Die Ergebnisse der drei Abfragen können wir mittels UNION zusammenfassen. Damit hätten wir dann die letzten drei Spiele eines jeden Spielers ermittelt. Bleibt also nur noch die Bildung der Summe.

SELECT s.name, SUM(s.punkte) AS punkte  
  FROM spiele_tabelle s  
  JOIN (  
         SELECT s.name, MAX(s.spiel)  
           FROM spiele_tabelle s  
          GROUP BY name  
  
         UNION  
  
         SELECT s.name, MAX(s.spiel)  
           FROM spiele_tabelle s  
          WHERE s.spiel < (  
                SELECT MAX(s1.spiel)  
                   FROM spiele_tabelle s1  
                  WHERE s1.name = s.name  
                 )  
           GROUP BY name  
  
         UNION  
  
         SELECT s.name, MAX(s.spiel)  
           FROM spiele_tabelle s  
          WHERE s.spiel < (  
                SELECT MAX(s1.spiel)  
                  FROM spiele_tabelle s1  
                 WHERE s1.name = s.name  
                   AND s1.spiel < (  
                       SELECT MAX(s2.spiel)  
                         FROM spiele_tabelle s2  
                        WHERE s2.name = s.name  
                       )  
                )  
          GROUP BY name  
       ) AS t  
    ON ( t.name = s.name AND t.spiel = s.spiel )  
 GROUP BY s.name;  

Natürlich ist diese Query frei heruntergeschrieben und nicht getestet.

weiterhin schönen abend...

--
#selfhtml hat ein Forum?
sh:( fo:# ch:# rl:| br:> n4:& ie:{ mo:} va:) de:] zu:} fl:( ss:? ls:[ js:|