Skip to content

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.

SELECT <output> [, <output> …] -- 1 to 20 outputs
FROM <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.

KeywordMeaning
SELECTChoose report outputs: metrics or bounded expressions.
FROMChoose the data source (table).
WHEREFilter raw rows with AND-joined clauses.
ASName a calculated SELECT output.
GROUP BYAggregate by one or two dimensions.
HAVINGFilter aggregated rows by a SELECT output or alias.
ANALYZESelect a relative or inclusive calendar analysis window.
BUCKET BYBucket temporal results by auto, day, week, month, or patch.
COMPARE TOCompare against a previous or custom equal-length period.
IN TIME ZONEInterpret temporal buckets in an IANA timezone.
ORDER BYSort by an output or label.
LIMITCap the number of rows returned.
ANDCombine multiple WHERE or HAVING clauses.
INMatch against a list of values.
ASCSort ascending.
DESCSort descending (default).
RENDERChoose the report display kind.
WITHSet chart channels and appearance options.

Use these in SELECT to compute a value, and name the result with AS.

SyntaxDescription
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, games
from match_participants
group by player
having games >= 10
order by dpm desc
render 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.

LimitValue
Query text length4000 characters
Outputs per SELECT1–20
Grouping dimensions1–2
Default lookback30 days
Maximum lookback365 days
Default row limit10
Maximum rows returned25
Chart series1–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.

Each part of the language has its own page:

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 leaderboard

Best 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 leaderboard

Most-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 leaderboard

KDA 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 leaderboard

Damage 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 table

Daily 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)