From 623ce97a6caa3b859b7aedd279e82a5a5f000ce7 Mon Sep 17 00:00:00 2001 From: Manuel Raimann Date: Thu, 7 Nov 2024 19:39:06 +0100 Subject: [PATCH] Add region, min_hero_matches_per_player and max_hero_matches_per_player filters to hero win loss stats endpoint --- deadlock_analytics_api/routers/v2.py | 46 +++++++++++++++++++--------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/deadlock_analytics_api/routers/v2.py b/deadlock_analytics_api/routers/v2.py index 257f2bf..101e9b2 100644 --- a/deadlock_analytics_api/routers/v2.py +++ b/deadlock_analytics_api/routers/v2.py @@ -161,36 +161,54 @@ def get_hero_win_loss_stats( res: Response, min_badge_level: Annotated[int | None, Query(ge=0)] = None, max_badge_level: Annotated[int | None, Query(le=116)] = None, + min_hero_matches_per_player: Annotated[int | None, Query(ge=0)] = None, + max_hero_matches_per_player: int = None, min_unix_timestamp: Annotated[int | None, Query(ge=0)] = None, - max_unix_timestamp: Annotated[int | None, Query(le=4070908800)] = None, + max_unix_timestamp: int | None = None, match_mode: Literal["Ranked", "Unranked"] | None = None, + region: ( + Literal["Row", "Europe", "SEAsia", "SAmerica", "Russia", "Oceania"] | None + ) = None, ) -> list[HeroWinLossStat]: limiter.apply_limits( req, res, "/v2/hero-win-loss-stats", [RateLimit(limit=100, period=1)] ) res.headers["Cache-Control"] = "public, max-age=1200" query = """ - SELECT hero_id, - countIf(team == mi.winning_team) AS wins, - countIf(team != mi.winning_team) AS losses - FROM default.match_player - INNER JOIN match_info mi USING (match_id) - WHERE ranked_badge_level IS NULL OR (ranked_badge_level >= %(min_badge_level)s AND ranked_badge_level <= %(max_badge_level)s) - AND mi.start_time >= toDateTime(%(min_unix_timestamp)s) AND mi.start_time <= toDateTime(%(max_unix_timestamp)s) - AND (%(match_mode)s IS NULL OR mi.match_mode = %(match_mode)s) + WITH filtered_players AS ( + SELECT hero_id, account_id, countIf(team == mi.winning_team) AS player_wins, countIf(team != mi.winning_team) AS player_losses + FROM match_player + INNER JOIN match_info mi USING (match_id) + INNER JOIN player p USING (account_id) + WHERE 1=1 + AND (ranked_badge_level IS NULL OR %(min_badge_level)s IS NULL OR ranked_badge_level >= %(min_badge_level)s) + AND (ranked_badge_level IS NULL OR %(max_badge_level)s IS NULL OR ranked_badge_level <= %(max_badge_level)s) + AND (%(min_unix_timestamp)s IS NULL OR mi.start_time >= toDateTime(%(min_unix_timestamp)s)) + AND (%(max_unix_timestamp)s IS NULL OR mi.start_time <= toDateTime(%(max_unix_timestamp)s)) + AND (%(match_mode)s IS NULL OR mi.match_mode = %(match_mode)s) + AND (%(match_mode)s IS NULL OR mi.match_mode = %(match_mode)s) + AND (%(region)s IS NULL OR p.region_mode = %(region)s) + GROUP BY hero_id, account_id + ) + SELECT hero_id, sum(player_wins) AS wins, sum(player_losses) AS losses + FROM filtered_players + WHERE (%(min_hero_matches)s IS NULL OR player_wins + player_losses <= %(min_hero_matches)s) + AND (%(max_hero_matches)s IS NULL OR player_wins + player_losses <= %(max_hero_matches)s) GROUP BY hero_id - HAVING wins + losses > 100 ORDER BY wins + losses DESC; """ with CH_POOL.get_client() as client: result = client.execute( query, { - "min_badge_level": min_badge_level or 0, - "max_badge_level": max_badge_level or 116, - "min_unix_timestamp": min_unix_timestamp or 0, - "max_unix_timestamp": max_unix_timestamp or 4070908800, + "min_badge_level": min_badge_level, + "max_badge_level": max_badge_level, + "min_unix_timestamp": min_unix_timestamp, + "max_unix_timestamp": max_unix_timestamp, "match_mode": match_mode, + "region": region, + "min_hero_matches": min_hero_matches_per_player, + "max_hero_matches": max_hero_matches_per_player, }, ) return [HeroWinLossStat(hero_id=r[0], wins=r[1], losses=r[2]) for r in result]