From 89a38784eddbf7cf0011a9f2f2ce94c177587957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Ke=C3=9Fler?= Date: Thu, 23 Nov 2023 16:19:10 +0100 Subject: [PATCH] Fix bug: User ratings not retrieved correctly --- ratings.py | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/ratings.py b/ratings.py index 5a52c96..6ff7521 100644 --- a/ratings.py +++ b/ratings.py @@ -47,15 +47,29 @@ def get_current_user_ratings(user_ids: List[int], rating_type: int) -> Dict[int, user_ids + [rating_type] ) base_ratings = cur.fetchall() + + # This query is a bit tricky: + # The subclause transforms the user_ratings table into the same table (with lesse columns), except that we now + # group entries corresponding to the same (user_id, type) and replace all of them with just the maximum league id + # Then we can do an inner join with this specific table, where we join again on (user_id, type), but now also + # require that the league id matches the max_league_id column from the subclause-generated table. + # Since an inner join only returns rows that match both tables, this will act as a filter on the initial table, + # even though we do not retrieve any values from the subclause-table cur.execute("SELECT user_ratings.user_id, value_after FROM user_ratings " "INNER JOIN (" - " SELECT user_id, type, MAX(league_id) AS max_league_id" - " FROM user_ratings " - " GROUP BY (user_id, type)" - " ) AS latest_user_ratings " - " ON user_ratings.league_id = latest_user_ratings.max_league_id " - "WHERE user_ratings.user_id IN ({}) AND user_ratings.type = %s".format(", ".join("%s" for _ in user_ids)), - user_ids + [rating_type] + " SELECT user_id, type, MAX(league_id) AS max_league_id" + " FROM user_ratings " + " GROUP BY (user_id, type)" + " ) AS latest_user_ratings " + " ON" + " user_ratings.league_id = latest_user_ratings.max_league_id" + " AND user_ratings.user_id = latest_user_ratings.user_id" + " AND user_ratings.type = latest_user_ratings.type " + "WHERE " + " user_ratings.user_id IN ({})" + " AND user_ratings.type = %s" + .format(", ".join("%s" for _ in user_ids)) + , user_ids + [rating_type] ) current_ratings = cur.fetchall() @@ -70,13 +84,17 @@ def get_current_user_ratings(user_ids: List[int], rating_type: int) -> Dict[int, def get_current_variant_rating(variant_id: int, player_count: int) -> float: cur = conn_manager.get_new_cursor() + # Again, this query is tricky. For explanation, see the corresponding query for the user ratings cur.execute("SELECT value_after FROM variant_ratings " "INNER JOIN (" - " SELECT variant_id, player_count, MAX(league_id) AS max_league_id" - " FROM variant_ratings " - " GROUP BY (variant_id, player_count)" - " ) AS latest_variant_ratings " - " ON variant_ratings.league_id = latest_variant_ratings.max_league_id " + " SELECT variant_id, player_count, MAX(league_id) AS max_league_id" + " FROM variant_ratings " + " GROUP BY (variant_id, player_count)" + " ) AS latest_variant_ratings " + " ON" + " variant_ratings.league_id = latest_variant_ratings.max_league_id " + " AND variant_ratings.variant_id = latest_variant_ratings.variant_id " + " AND variant_ratings.player_count = latest_variant_ratings.player_count " "WHERE variant_ratings.variant_id = %s AND variant_ratings.player_count = %s", (variant_id, player_count) )