PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Probleme beim Kombinieren von HAVING mit WHERE bei einer sehr einfachen QUERY

Ich habe keinen PostgreSQL-Hintergrund, aber mal sehen, ob das funktioniert:

Ich würde damit beginnen, es zu vereinfachen, indem ich eine Abfrage schreibe, die zuerst die Gesamtpunktzahl pro Spieler zurückgibt:

SELECT player_id, SUM(score) score
FROM (
  SELECT first_player as player_id, first_score as score
  FROM matches
  UNION ALL
  SELECT second_player, second_score
  FROM matches
)
GROUP BY player_id

Verbinden Sie nun diesen Datensatz mit Spielern, um die Gruppen zu finden:

SELECT w.player_id, p.group_id, w.score
FROM
(
  SELECT player_id, SUM(score) score
  FROM (
    SELECT first_player as player_id, first_score as score
    FROM matches
    UNION ALL
    SELECT second_player, second_score
    FROM matches
  )
  GROUP BY player_id
) as w
inner join players p
on p.player_id = w.player_id

Jetzt haben wir alle Spieler, ihre Gesamtpunktzahl und ihre Gruppe. Wir wollen den Gewinner nach Gruppe ermitteln? Wir können Ranking verwenden Funktionen dazu:

SELECT 
w.player_id, 
p.group_id, 
w.score, 
RANK() OVER (PARTITION BY p.group_id ORDER BY score DESC) as group_placement
FROM
(
  SELECT player_id, SUM(score) score
  FROM (
    SELECT first_player as player_id, first_score as score
    FROM matches
    UNION ALL
    SELECT second_player, second_score
    FROM matches
  )
  GROUP BY player_id
) as w
inner join players p
on p.player_id = w.player_id

Jetzt wählen wir einfach die Besten in jeder Gruppe (Rang =1) mit WHERE aus

  SELECT 
  player_id, 
  group_id
  FROM
  (
      SELECT 
      w.player_id, 
      p.group_id, 
      w.score, 
      RANK() OVER (PARTITION BY p.group_id ORDER BY score DESC) as group_placement
      FROM
      (
        SELECT player_id, SUM(score) score
        FROM (
          SELECT first_player as player_id, first_score as score
          FROM matches
          UNION ALL
          SELECT second_player, second_score
          FROM matches
        )
        GROUP BY player_id
      ) as w
      inner join players p
      on p.player_id = w.player_id
    ) as gp
    WHERE group_placement = 1

Sieht kompliziert aus? ja, aber man sieht schon das Endergebnis wird nach und nach bereitgestellt. Jeder Schritt davon ist eine „Untertabelle“, und Sie können die Daten an jedem Punkt ausführen und beobachten.