ScoutQL
ScoutQL is the query language used by reports. It is SQL-shaped but not SQL: the clauses, sources, and outputs are a fixed vocabulary, and a query compiles to a validated plan rather than to arbitrary SQL.
Keywords are case-insensitive.
Clause order
Section titled “Clause order”SELECT <output> [, <output> …] -- 1 to 20 outputsFROM <source>[WHERE <clause> [AND <clause> …]]GROUP BY <dimension> [, <dimension>] -- 1 or 2[HAVING <clause> [AND <clause> …]][ORDER BY <output|label> [ASC|DESC]][LIMIT <n>][RENDER <kind> [WITH (<option> = <value>, …)]]SELECT, FROM, and GROUP BY are required. Omitting RENDER produces a
table.
Keywords
Section titled “Keywords”| Keyword | Meaning |
|---|---|
SELECT | Choose report outputs: metrics or bounded expressions. |
FROM | Choose the data source (table). |
WHERE | Filter raw rows with AND-joined clauses. |
AS | Name a calculated SELECT output. |
GROUP BY | Aggregate by one or two dimensions. |
HAVING | Filter aggregated rows by a SELECT output or alias. |
ANALYZE | Select a relative or inclusive calendar analysis window. |
BUCKET BY | Bucket temporal results by auto, day, week, month, or patch. |
COMPARE TO | Compare against a previous or custom equal-length period. |
IN TIME ZONE | Interpret temporal buckets in an IANA timezone. |
ORDER BY | Sort by an output or label. |
LIMIT | Cap the number of rows returned. |
AND | Combine multiple WHERE or HAVING clauses. |
IN | Match against a list of values. |
ASC | Sort ascending. |
DESC | Sort descending (default). |
RENDER | Choose the report display kind. |
WITH | Set chart channels and appearance options. |
Functions
Section titled “Functions”Use these in SELECT to compute a value, and name the result with AS.
| Syntax | Description |
|---|---|
round(<expression>[, <digits>]) AS <alias> | Round a calculated value to 0–10 decimal places. |
coalesce(<expression>, <fallback>) AS <alias> | Use a numeric fallback when an expression is null. |
per_game(<expression>) AS <alias> | Divide an aggregate by games played. |
per_minute(<expression>) AS <alias> | Divide an aggregate by total minutes played. |
select per_minute(damage_to_champions) as dpm, gamesfrom match_participantsgroup by playerhaving games >= 10order by dpm descrender bar_chart with (y = dpm)HAVING filters on aggregated outputs, including aliases you define with AS.
WHERE filters raw rows before aggregation. Filtering on games requires
HAVING or the aggregate games >= <n> form, because a raw row is a single
game.
Limits
Section titled “Limits”| Limit | Value |
|---|---|
| Query text length | 4000 characters |
| Outputs per SELECT | 1–20 |
| Grouping dimensions | 1–2 |
| Default lookback | 30 days |
| Maximum lookback | 365 days |
| Default row limit | 10 |
| Maximum rows returned | 25 |
| Chart series | 1–8 |
Lookback and maximum rows are report settings, not query syntax — set them
on the report form alongside the schedule. A LIMIT larger than the maximum is
capped at execution.
Vocabulary
Section titled “Vocabulary”Each part of the language has its own page:
- Sources and dimensions — what
FROMandGROUP BYaccept. - Metrics — what
SELECTaccepts. - Filters — what
WHEREaccepts. - Render kinds and options — what
RENDERandWITHaccept.
Worked examples
Section titled “Worked examples”These are the presets built into the report editor.
Most games played
Find the most active players over the lookback window.
select games, win_rate from match_participants group by player order by games desc limit 10 render leaderboardBest win rate (ranked solo, min 10 games)
Rank players by solo queue win rate with a games floor.
select games, win_rate from match_participants where queue in (solo) and games >= 10 group by player order by win_rate desc render bar_chart with (y = win_rate)Surrender-happy champions
Spot champions most associated with surrender losses.
select games, surrender_rate from match_participants group by champion order by surrender_rate desc limit 10 render leaderboardMost-played champions
Show which champions the server has been playing most.
select games, win_rate from match_participants group by champion order by games desc limit 10 render bar_chart with (y = games)Most active teammate groups
List teammate groups of every size (group(2) picks duos only) by games together.
select games, win_rate from player_groups group by group(all) order by games desc limit 10 render leaderboardKDA leaders
Rank players by KDA with a minimum games filter.
select games, kda from match_participants where games >= 5 group by player order by kda desc limit 10 render leaderboardDamage leaders
Find who dealt the most champion damage.
select games, damage_to_champions from match_participants group by player order by damage_to_champions desc limit 10 render bar_chart with (y = damage_to_champions)Champion-select picks
Use lobby observations to see planned champion picks.
select prematches from prematch_participants group by champion order by prematches desc limit 10 render bar_chart with (y = prematches)Queue mix
Break recent server activity down by queue.
select games, win_rate from match_participants group by queue order by games desc render tableDaily activity trend
Follow daily game volume with a smoothed filled trend.
select games from match_participants group by all analyze last 30 days bucket by day in time zone 'UTC' order by label asc render area_chart with (y = games, title = "Daily games", palette = gold, smooth = true, trend = true, sparkline = true)Weekly wins and losses
Compare weekly wins and losses as stacked bars.
select wins, losses from match_participants group by all analyze last 90 days bucket by week compare to previous period in time zone 'UTC' order by label asc render stacked_bar with (y = (wins, losses), palette = team, labels = value)Win/loss share
Show the share of recent games by outcome.
select games from match_participants group by outcome order by games desc render donut_chart with (y = games, title = "Recent outcomes", labels = percent)Combat efficiency map
Compare player damage per game with KDA and game volume.
select games, per_game(damage_to_champions) as damage_per_game, kda from match_participants group by player having games >= 5 order by damage_per_game desc render scatter_chart with (x = damage_per_game, y = kda, size = games, palette = colorblind)Champion position heatmap
Reveal champion win-rate pockets across team positions.
select games, win_rate from match_participants group by champion, team_position having games >= 3 order by games desc limit 80 render heatmap with (x = champion, series = team_position, value = win_rate, palette = ranked, labels = value)Champion combat profiles
Compare per-game combat and vision profiles for active champions.
select games, per_game(kills) as kills_per_game, per_game(assists) as assists_per_game, per_game(damage_to_champions) as damage_per_game, per_game(vision_score) as vision_per_game from match_participants group by champion having games >= 5 order by games desc limit 6 render radar_chart with (y = (kills_per_game, assists_per_game, damage_per_game, vision_per_game), legend = top, palette = categorical)Server KPI snapshot
Summarize activity, win rate, KDA, and game length in one card.
select games, win_rate, kda, avg_game_duration from match_participants group by all render kpi_card with (y = (games, win_rate, kda, avg_game_duration), title = "30-day snapshot", theme = minimal_dark)Damage per gold
Rank players by champion damage produced per gold earned.
select games, round(damage_to_champions / gold_earned, 3) as damage_per_gold from match_participants group by player having games >= 5 order by damage_per_gold desc limit 15 render bar_chart with (y = damage_per_gold, orientation = horizontal, palette = gold, labels = value)Weekly vision trend
Track wards and vision score per game over time.
select per_game(vision_score) as vision_per_game, per_game(wards_placed) as wards_per_game, per_game(wards_killed) as wards_killed_per_game from match_participants group by all analyze last 90 days bucket by week in time zone 'UTC' order by label asc render line_chart with (y = (vision_per_game, wards_per_game, wards_killed_per_game), palette = colorblind, legend = bottom, smooth = true, rolling = 3)Arena placement share
Break Arena games down by final placement.
select arena_games from match_participants group by arena_placement having arena_games >= 1 order by label asc render donut_chart with (y = arena_games, palette = ranked, labels = percent)Objective pressure leaders
Combine objective and turret damage into a per-game pressure score.
select games, per_game(damage_to_objectives + damage_to_turrets) as objective_pressure from match_participants group by player having games >= 5 order by objective_pressure desc limit 12 render bar_chart with (y = objective_pressure, orientation = horizontal, palette = team)First blood by position
Compare first-blood rates across team positions.
select games, first_blood_rate from match_participants group by team_position having games >= 10 order by first_blood_rate desc render bar_chart with (y = first_blood_rate, palette = ranked, labels = percent)Game length trend
Track average match duration by week.
select avg_game_duration from match_participants group by all analyze last 120 days bucket by week in time zone 'UTC' order by label asc render line_chart with (y = avg_game_duration, title = "Average game length", y_axis = "Minutes", smooth = true, trend = true)Surrender trend
Follow total and early surrender rates by week.
select surrender_rate, early_surrender_rate from match_participants group by all analyze last 120 days bucket by week compare to previous period in time zone 'UTC' order by label asc render area_chart with (y = (surrender_rate, early_surrender_rate), palette = colorblind, labels = hide, smooth = true, rolling = 3)