Query (PPQL) — historical_games, 1999–present
New here? That's just a sample query so you have something to look at — type over it, or use the plain-English box above instead.
Typing after
stadium=, officials=, or surface= pops up matching values — click one, or arrow-key + Enter/Tab to pick it, so you never have to remember the exact spelling.Run a query to see available columns.
Saved queries
Result significance
Run a query above to see its record, ROI/profit, and per-game averages here.
Record after a loss — how the system does on the very next game, immediately following one of its own losses
—
—
—
Matching rows
Field reference
Browse all ~150 fields, live from the server, plus shortcuts — click any field to insert it
Loading field list…
Numeric field stats ?
Count / sum / mean / median / std / variance / quartiles / min / max for every numeric field
| Field | Count | Sum | Mean | Median | Std | Variance | Q1 (25%) | Q3 (75%) | Min | Max |
|---|
Numeric field stats — what each column means
Count
How many rows in this result set had a real (non-null) value for this field. Rows missing the field aren't counted.
Sum
Every value for this field, added together.
Mean
The average — Sum divided by Count.
Median
The middle value once everything is sorted low to high. Less thrown off by a few extreme outliers than Mean is.
Std (standard deviation)
How spread out the values are around the Mean. A small Std means most values sit close to the Mean; a large one means they're scattered.
Variance
Std squared — same idea, just in squared units. Std is usually the easier of the two to read.
Q1 (25%) / Q3 (75%)
Quartiles: 25% of values fall below Q1, and 75% fall below Q3. Together with the Median (the 50% mark) they show how the data is distributed, not just its average.
Min / Max
The smallest and largest value seen for this field in the result set.
Only want certain fields? Type into the
Filter fields box above the table — e.g. type passing to instantly narrow this list down to just passing-related fields.Query syntax & examples
Operators, ranges, prefixes (tpS, p:/n:/o:), shortcut fields (PPG, 3DPCT...), and field coverage notes
Combine with
Set membership:
Season lookback:
Previous/next games:
Numeric shortcut for any of the above: a count instead of repeating the letter —
All accept the
Previous-season streak:
Season-long condition (no field name required — a whole comparison instead):
A prefix can also be used as a VALUE instead of a whole condition —
A field can be compared against a number times ANOTHER field —
Group by any field right in the query text with
Shortcut fields:
Matchup shortcuts:
Full field list is above, under "Field reference" (fetched live from the server, so it always matches what the parser actually accepts) — click any field to insert it.
Data coverage varies by field: schedule/box-score fields go back to 1999; PFR advanced stats (bad throws, pressures, hurries, etc.) start 2018; Next Gen Stats fields start 2016; officials start 2015;
Use the grouping dropdown to break a query's record out by season/team/week/etc. instead of one combined total — e.g.
and / or. Ranges: 9.5>=line>=3.5 — the middle term can also be a season-aggregate call, e.g. 28>=tA(points)>=21 or 28>=oA(points)>=21.Set membership:
field in [v1, v2, ...] / field not in [v1, v2, ...] — e.g. team in ['KC','BUF','SF'] instead of chaining team='KC' or team='BUF' or team='SF' by hand. Works inside prefixes too, e.g. o:team in ['KC','BUF'] = today's opponent is one of those teams. Values follow the same quoting rules as a normal comparison (quoted string, number, or bareword) and are typed per-field, so season in [2023,2024] parses each as a number.Season lookback:
tpS(field) = this team's SUM over its previous season, tppS(field) = two seasons back,
tpA(field) / tppA(field) = AVERAGE instead of sum, tpMAX(field) / tppMAX(field) = MAX, tpMIN(field) / tppMIN(field) = MIN — S/A/MAX/MIN are the four aggregate kinds. Two calls can combine with one operator:
tpS(completions)/tpS(passes)>=0.64, or e.g. tpMAX(wins)>=6 = won at least 6 games in some previous season.
Opponent-anchored shorthand: oA(field)/oS(field)/oMAX(field)/oMIN(field) — same as tA()/etc. but for the same-game OPPONENT's own season, no colon needed (equivalent to the longer o:tA(field) form). Nests: oA(o:points) = what the opponent ALLOWS per game (their own PAPG), while bare oA(points) = what the opponent scores per game.Previous/next games:
p:/pp:/... (back) and n:/nn:/... (forward) — e.g. p:H and pp:H and ppp:H = last 3 games were all home.
Head-to-head: P:/PP:/... (previous meeting vs today's opponent) and N:/NN:/... (next meeting) — e.g. P:W = won the previous meeting against this opponent.
Opponent's own games: op:/opp:/... and on:/onn:/.... Same game, opponent's side: o: — e.g. o:points>=30.
Compound (add a trailing "o" to any of the above): reaches the referenced game, THEN that game's own opponent — po:points>=100 = in my previous game, the team I played scored 100+; opo:points>=24 = in my current opponent's own previous game, the team THEY played scored 24+.Numeric shortcut for any of the above: a count instead of repeating the letter —
p3: = ppp:, p7: = ppppppp:, op5: = oppppp:, N2: = NN: — e.g. p7:points>=24 instead of spelling out seven p's.All accept the
H/A/N/W/L shortcuts (home/away/neutral site, win/loss) — these also work bare at the top level of a query, e.g. team='DAL' and H and W. Windowed count: tS(cond,N=k) — e.g. tS(W,N=3)>=2 = won at least 2 of its last 3 games.Previous-season streak:
STREAKPREV(N,W) / STREAKPREV(N,L) — matches when this team's LAST N games of its PREVIOUS season were all wins (W) or all losses (L), correctly anchored to the prior season no matter what week of the CURRENT season you're querying from. This is different from p:L and pp:L, which have no season boundary and drift into the current season's own games once enough of them exist (e.g. at week 8, p:L and pp:L means weeks 6-7 of THIS season, not last season's finish) — e.g. STREAKPREV(2,L) = lost its last 2 games of last season, regardless of the current week. W/L here use the same ATS (against-the-spread) definition as the bare W/L shortcuts, not straight-up.Season-long condition (no field name required — a whole comparison instead):
tS(cond) = COUNT of games this season/prior season where cond holds, tA(cond) = the FRACTION (0-1) of such games — same tp/tpp lookback and opponent-anchor shorthand as the field form. E.g. tpA(atsmargin>0)*100>=65 = covered the spread in at least 65% of last season's games (note: field names have no underscore — atsmargin, not ats_margin — and this returns a 0-1 fraction unless you add *100, same convention as 3DPCT below). tpS(atsmargin>0)>=11 = covered at least 11 games last season.A prefix can also be used as a VALUE instead of a whole condition —
field>prefix:field2 — e.g. points>o:points = outscored the opponent, line<=p:line = today's line is at or below the previous game's.A field can be compared against a number times ANOTHER field —
field OP number*field2 (either order) — e.g. -line>=.4*total = the favorite is laying at least 40% of the total.Group by any field right in the query text with
@field instead of the dropdown below — e.g. season=2025 @team = one row per team for the 2025 season. Each group's breakdown now also includes a numeric stats block (sum/mean/etc.) for whatever's in "stats fields," so e.g. total interceptions per team is right there per group, not just the W-L-P record.Shortcut fields:
PPG = points scored per game this season, PAPG = points ALLOWED per game (defense), YPPT = total yards per point (season), 3DPCT/4DPCT/RZPCT/COMP = third-down/fourth-down/red-zone/completion conversion percentage (season — an actual percentage, use >=45, not >=.45). All work as a bare comparison (PPG>=27, 3DPCT>=45, COMP>=64) or inside a prefix (o:PPG>=27 = what today's opponent scores on offense; o:PAPG>=27 = what they allow on defense; o:3DPCT>=45 = opponent's own third-down rate). Named 3DPCT/4DPCT rather than "TD"/"FD" on purpose — TD reads as touchdown at a glance.Matchup shortcuts:
DIV/NDIV = this team and today's opponent do/don't share a division, CONF/NCONF = do/don't share a conference. Unlike the shortcuts above these are whole boolean conditions, not values — use them bare, e.g. team='DAL' and DIV or NCONF and points>=30. Use NDIV/NCONF to negate rather than not DIV/not CONF, which aren't supported.gamenumber is this team's real Nth game of the season (byes don't count) — different from week, which can skip a number on a bye week. Use it for "first 6 games" style filters where a bye would otherwise throw off a week-based cutoff.Full field list is above, under "Field reference" (fetched live from the server, so it always matches what the parser actually accepts) — click any field to insert it.
Data coverage varies by field: schedule/box-score fields go back to 1999; PFR advanced stats (bad throws, pressures, hurries, etc.) start 2018; Next Gen Stats fields start 2016; officials start 2015;
scoredfirst/biggestlead/leadchanges/timestied/siq are only populated for seasons the play-by-play import has been run for. A field with no data for a given season simply returns no match for that season, rather than erroring.siq ("scored in quarter") is the count of quarters this team scored in — 4 if they scored in every regulation quarter, 5 if they also scored in OT. Works like any other numeric field, e.g. siq=4, siq>=3, or tA(siq)>=3.5 for a season-to-date average.Use the grouping dropdown to break a query's record out by season/team/week/etc. instead of one combined total — e.g.
team='PHI' grouped by season shows one row per year. Click any breakdown row to drill into the individual games behind it.