# Football Query — reference for language models

Football Query answers questions about men's international football (47,004 matches, 215 national teams, 1872–2026; results from openfootball/internationals @ a29e7cc, merged with martj42/international_results, the Fjelstul World Cup Database and ESPN for later results, scorers, line-ups and cards). People build questions visually from "pills"; underneath, every question is one JSON **query** — a tree of **blocks**. You can write that JSON directly and run it.

Human guide: /guide. This file: /llms.txt.

## How to answer a question

1. Translate the question into a Query (types below). Start from the entity the answer is a list of.
2. If you can make HTTP requests, check it: `POST https://fq.rking.ie/api/run` with `{ "query": <Query> }` for the answer (`rows`, `total`), or `GET https://fq.rking.ie/api/link?q=<URL-encoded JSON>` for its link, sentence and outline (see "Links").
3. Reply to the person with, in this order:
   - **the answer**, if you ran it;
   - **Reads as** — the query in the app's own words (the sentence shown above the canvas);
   - **On the canvas** — the outline below, in a code block, so they can build it pill by pill;
   - **a link** that opens it in the builder, ready to run and edit (saving it to a library needs the user signed in with Google).
4. State caveats that apply (see "Data caveats"): goal and player totals are lower bounds, for example.

Example reply:

> **Reads as:** Find England, that played matches where result is Win and competition is FIFA World Cup.
>
> **On the canvas:**
> ```
> FIND Team  [hidden]
>   WHERE Name is "England"
>   THAT played Match
>     WHERE Result is Win
>     AND Competition is "FIFA World Cup"
> ```
>
> **Open it:** https://fq.rking.ie/?q=%7B%22q%22%3A%7B%22root%22%3A%7B%22entity%22%3A%22team%22%2C%22shown%22%3Afalse%2C%22items%22%3A%5B%7B%22property%22%3A%22name%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22England%22%7D%5D%2C%22children%22%3A%5B%7B%22entity%22%3A%22match%22%2C%22relation%22%3A%22played%22%2C%22items%22%3A%5B%7B%22property%22%3A%22result%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22Win%22%7D%2C%7B%22property%22%3A%22competition%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22FIFA%20World%20Cup%22%7D%5D%7D%5D%7D%7D%7D

## Showing the query to the person

The builder shows a query two ways, and your reply should too.

**The canvas outline** — one line per row of pills, exactly as the canvas lays them out:

- `FIND <Entity>` starts the query with the root block (Team, Match, Tournament, Goal, Player, Card, Appearance).
- Conditions sit under their block, indented two spaces: `WHERE <Property> <operator> <value>` for the first, then `AND` (or `OR`, when the block's `join` is "or") for each next one. A condition group reads `AND (<cond> OR <cond>)`.
- A child block is `THAT <relation label> <Entity>`, indented under its parent, its own conditions indented under it. Use the relation's **label on canvas** from the Relations table (`played`, `played by`, `was won by`…), or its **negated label** when the block is negated (`never played`). Sibling blocks joined by `childJoin: "or"` read `OR` instead of `THAT`.
- Tags in brackets after a block: `[hidden]` (only filters), `[if any]` (optional), `[as ‹A›]` (alias), `[named “…”]` (label).
- Properties use their **label on canvas** from the Properties tables (`Name`, `Result`, `Competition`), operators their label from the Operators table (`is`, `is any of`, `≥`, `in the last`).
- Values: typed names and text in double quotes (`Name is "England"`); choices from a list, numbers and dates bare (`Result is Win`, `Goals ≥ 10`, `Date after 2014-07-13`); yes/no as `yes` / `no`; another block's value as `‹A›` or `‹A›'s End date`.
- A player's run: `THAT has a Run of Starts across competitive matches`.
- A streak: `THAT has a Streak of Wins across all matches`, with `COUNTS …` / `ACROSS …` lines for custom conditions and `KEEP the longest`.
- Closing clauses, unindented: `⟶ PER <column>` with a measure per line (`COUNT Matches`, `COUNT Wins`, `TOTAL Goals for`, `CALC Won as % of Played`); `⟶ KEEP where <column> <op> <value>`; `⟶ KEEP top 10 by <column>, highest first` (`THEN KEEP top…` after a keep-where). A column from a block above the row is prefixed with it: `Team · Name`.

**The "Reads as" sentence** — the same query in plain English, e.g. "Find England, that played matches where result is Win and competition is FIFA World Cup." `/api/link` returns both the exact sentence and the exact outline; without it, write them in the style above and of the worked examples.

## Links

**Readable link** — the site address, `/?q=`, then the query JSON, URL-encoded (as JavaScript's `encodeURIComponent` does):

`https://fq.rking.ie/?q=` + encodeURIComponent(JSON.stringify({ "q": <Query>, "v": <View> }))

- `v` (columns, sort, table or graph) is optional, and so is the `{ q }` wrapper: a bare Query, or just its root Block, works too.
- You may leave out ids, `join`, `items`, `shown` (default true), `children`, `kind`, `v`, `grouping` and `ranking`; they're filled in. Give an id to any block or measure something refers to — e.g. `{ "id": "s", "entity": "streak", … }` for `"ranking": { "column": "s.length", … }` — because a ref to an id that doesn't exist is silently ignored when the query runs (`/api/link` reports it as an error).
- Encode every character outside letters, digits and `-_.!~*'()` — at least `"`, spaces, `{` `}` `[` `]`, `:`, `,`, `#`, `&`, `%`, `+` and accented letters (`é` → `%C3%A9`).
- Opening it runs the query in the builder; the address then switches to the app's own compact form, which is what its *Share link* copies.

Short JSON for the example above: `{"q":{"root":{"entity":"team","shown":false,"items":[{"property":"name","op":"is","value":"England"}],"children":[{"entity":"match","relation":"played","items":[{"property":"result","op":"is","value":"Win"},{"property":"competition","op":"is","value":"FIFA World Cup"}]}]}}}`

**Checked link** — `GET https://fq.rking.ie/api/link?q=<URL-encoded JSON>` (or `POST` the JSON as the body) runs the query first and returns `{ ok, url, readableUrl, sentence, outline, total, rows, query }` — or `{ ok: false, error }` if it doesn't run. Prefer it when you can make requests: it catches mistakes before the person sees them.

**Compact form** — `/?s=j<base64url(JSON.stringify({ q, v }))>` (no padding) is what the app writes; `/api/link` returns it as `url`.

## API

- `POST /api/run` — body `{ query, view?, drill?, page?, pageSize?, chart? }`.
  - `view`: `{ columns?: string[] | null, sort?: { column, dir: "asc" | "desc" } | null }` — presentation only.
  - `page` (0-based) and `pageSize` (1–500, default 100) page the rows; ranking and sorting happen first.
  - `drill`: for a grouped query, the key cells of one group — returns the rows behind that group.
  - `chart`: `{ kind: "bars" | "counts" | "histogram" | "timeline" | "scatter" | "stacked" | "line", x?, y?, ys?, split?, start?, end?, bin? }` with column refs — returns aggregated `chart` data over all rows.
  - Response: `{ ok: true, rowEntity, rowLabel, columns: [{ ref, label, type }], rows: unknown[][], total, page, pageSize, notes: string[], rowMeta, cellRefs, available, chart, varies }`, or `{ ok: false, error }`.
  - `available` lists every column ref you could put in `view.columns` for this row shape.
- `GET /api/team/:id`, `/api/tournament/:id`, `/api/player/:id`, `/api/goal/:id`, `/api/match/:id?focus=teamId`, `POST /api/streak { team, start, spec }` — details for one entity. Ids come from `rowMeta[i].ref` and `cellRefs[i][j]` in a run result.
- `GET /api/suggest?source=player&q=mbappe` — player names as the data spells them.
- `GET/POST /api/library` — the signed-in user's saved queries and shortcuts. It needs a browser session (Google sign-in), so it isn't for you: link the person to the query and let them press *Save*.
- Full pages, for linking a person to one thing: `/team/:id`, `/player/:id`, `/match/:id?focus=teamId`, `/tournament/:id` (team and player pages take `?from=YYYY&to=YYYY&ground=Home|Away|Neutral&type=Finals|Qualification|Friendly`), and `/goal/:id`, which opens its match. Ids come from `rowMeta` and `cellRefs`; players are renumbered whenever the data is rebuilt, so prefer a query link for anything lasting.

## Query shape (TypeScript)

```ts
type Query = { v: 1; root: Block | null; grouping: Grouping | null; ranking: Ranking | null; keep?: Condition[]; once?: boolean };

type Block = {
  id: string;                    // unique in the query; column refs are "<blockId>.<propertyKey>". Never "m": "m.<id>" means a measure
  entity: "team" | "match" | "tournament" | "goal" | "player" | "card" | "appearance" | "streak";
  relation: RelationId | null;   // how it hangs off its parent; null for the root
  mode?: "required" | "optional" | "without";   // default required
  join: "and" | "or";            // between this block's conditions
  childJoin?: "and" | "or";      // between its child blocks (default and)
  items: (Condition | ConditionGroup)[];
  shown: boolean;                // hidden blocks only filter
  children: Block[];
  streak?: StreakSpec;           // required when entity is "streak"
  label?: string;                // display name
  alias?: string;                // name other conditions can refer to
};

type Condition = { id: string; kind: "cond"; property: string; op: Operator; value: Value };
type ConditionGroup = { id: string; kind: "group"; join: "and" | "or"; items: Condition[] };
type Value = string | number | boolean | string[] | number[]
  | { amount: number; unit: "days" | "weeks" | "months" | "years" }   // inLast / notInLast
  | { alias: string; prop?: string }                                  // another block's value
  | { col: string }                                                   // another column (keep / having only)
  | null;

type StreakSpec = {
  over?: "matches" | "editions";          // runs of a team's matches (default) or of a competition's editions; a player's runs (relation playerRun) are over matches
  condition: StreakCondition | "custom" | null;
  conditionItems: Condition[];            // when condition is "custom": match (or, over editions, tournament) conditions, all must hold
  scope: "all" | "competitive" | "finals" | "competition" | "custom";
  competitions: string[];                 // for scope "competition"; over editions, the first is the competition
  scopeItems: Condition[];                // when scope is "custom": match conditions
  keep: { kind: "recent" | "longest"; n: number } | null;   // keep only the N most recent / longest per team
};

type Grouping = {
  by: string[];                           // column refs; each distinct combination is one row
  measures: Measure[];
  having?: Condition[];                   // property = a column ref ("m.<measureId>" or a key); all must hold
};
type Measure = {
  id: string; label?: string;
  fn: "count" | "countWhere" | "countDistinct" | "sum" | "avg" | "max" | "min" | "first" | "last" | "calc";
  column?: string;                        // for countDistinct, sum, avg, max, min, first, last
  where?: Condition;                      // for countWhere: a condition on the row entity
  a?: string; b?: string; op?: "-" | "+" | "/" | "%";   // for calc: two other measure ids; "%" = a as % of b; two dates subtract to years
};
type Ranking = { column: string; dir: "desc" | "asc"; n: number; per?: string[]; ties?: boolean };
```

## Rules the engine follows

1. **Blocks are existence checks.** A parent binding passes if its conditions pass and each child block has at least one passing binding (`mode: "required"`). `optional`: the parent passes either way; with no match the child's columns are empty and counts are 0. `without`: the parent passes only if the child has no passing binding; a `without` block and everything under it must be hidden and never makes rows.
2. **`childJoin: "or"`** makes any one child enough instead of all.
3. **The row** is the deepest shown block (ties: first in canvas order). Rows are distinct by the row binding plus every shown block above it, plus hidden blocks that a clause, column or sort reads.
4. **Team in focus.** A match reached by `played`, `facedIn`, `scoredIn`, `playerScoredIn`, `appearedIn`, `startedIn`, `cameOnIn`, `shownIn`, `appearanceIn`, `contains`, `nextMatch` or `previousMatch` is seen from one side, which gives it team-relative properties (result, opponent, goalsFor, ground, elo, …). A tournament reached by `playedIn`, `won`, `nextEdition` or `previousEdition` has that team in focus (finish, group position, record there). A match or tournament with no inherited side that uses team-relative properties — or a match with a `sideOf`, `playedAgainst`, `goalsFor` or `nextMatch` child — is tried from every side that took part, so it can appear once per side. Likewise a match under a team root whose condition both sides pass (UEFA sides' matches) comes once per side; set `once: true` on the query to keep one row per match or tournament (the winner's view, or the first in ranking order), or start from `match` with a hidden `playedBy` team child. A player reached by `playedAlongside` or `playedAgainstPlayer` has the player above it in focus instead: it gains `sharedMatches`, `sharedStarts`, `sharedWins` and `pair`.
5. **Head-to-head:** root `match` with two hidden `playedBy` team children. **Opponent's properties:** under a focused match use `playedAgainst` (not `playedBy`, which is either side).
6. **"Never" questions:** negate the block that must not exist. "Teams that never played England" = team → `played` match (`mode: "without"`) → `playedAgainst` team (name is England). Exclude the subject itself where relevant (`name isNot England`).
7. **Text comparisons ignore case and accents.** Team names are current names; historical sides are merged into successors.
8. **Conditions with no value are ignored**, not errors. **Ids:** blocks, conditions and measures each need an id unique in the query. A column ref is `<blockId>.<key>`; `m.<measureId>` is a measure, so never give a block the id `m`.
9. **Order of clauses:** rows → grouping (by, measures, then `having`) or `keep` on plain rows → `ranking` (with `per`, top N within each value; with `ties`, rows equal to the Nth stay) → `view.sort` → paging. Empty values sort last.
10. **Aliases:** set `alias` on a block; any condition elsewhere may use `{ "alias": "A" }` (for `self`: same entity; for team/country fields: that team's name) or `{ "alias": "A", "prop": "date" }` (that block's property). Aliases compare within one row of the answer. Overlapping reigns: a title runs from `endDate` to `heldUntil`, so B overlaps alias A when B.endDate before A.heldUntil and B.heldUntil after A.endDate. An alias inside a `without` block can't be used outside it.
11. **Streaks** are maximal runs; a single match counts as a run of 1. `isActive`: the run includes the team's latest match in scope (for a player's run: nothing has broken it since their side's latest match with a known line-up). `isMostRecent` is judged among streaks passing the block's other conditions.
12. **Defaults:** without `view.columns`, each shown ancestor contributes its name and the row gets sensible default columns. Without ranking or sort, streaks come longest first, teams alphabetically, players by goals (then name), a run's member matches in date order, groups by their first measure (highest first), and everything else — matches, goals, cards, appearances, tournaments — newest first.

## Entities

| entity | meaning |
|---|---|
| `team` | A national side. Historical sides are merged into their FIFA-recognised successor. |
| `match` | One game between two teams. As a root, each game is one row. |
| `tournament` | One edition of a competition, e.g. World Cup 2014. Qualifying is split by calendar year in the source. |
| `goal` | One goal in one match, where the scorer was recorded. Scorers come from openfootball, martj42, the Fjelstul World Cup Database and ESPN; older friendlies mostly have none, so counts are lower bounds. |
| `player` | A player: a name and the side they played for, from line-ups, goals and cards. Line-ups are known for World Cups since 1970, most competitive matches since about 2003 and friendlies since about 2016 — before that, a player is here only if they scored or were booked. |
| `card` | A yellow or red card shown to a player. Known for World Cups since 1970 and, from ESPN, most competitive matches since about 2003 and friendlies since about 2016. |
| `appearance` | One player in one match's line-up — a start or a substitute's run-out — with their minutes, goals, cards and position. Only where line-ups are known. |
| `streak` | A maximal run of consecutive matches (or a competition's editions) for one team — or, for a player, of their side's matches or their own appearances. Not a root: reached from a team via `hasStreak`, or from a player via `playerRun`. |

## Relations

| id | from → to | label on canvas | negated label | notes |
|---|---|---|---|---|
| `played` | team → match | played | never played | gives the child a team in focus. Puts the team in focus: the match gains Result, Goals for, Opponent and the other team-relative properties. |
| `playedIn` | team → tournament | played in | never played in | gives the child a team in focus. Tournament editions the side played at least one match in. Puts the team in focus: the tournament gains Finish, Group position and its record there. |
| `hasStreak` | team → streak | has a | never had a | A run of consecutive matches, in date order, where a condition holds. You choose what the run is of, and which matches make up the sequence. |
| `playedBy` | match → team | played by | not played by | Either side. Two of these, side by side, express a head-to-head. |
| `playedAgainst` | match → team | played against | not played against | needs the parent match to have a team in focus. Only ever the other team. Use this — not played by — to filter on the opponent's properties, or the team in focus matches its own filter. |
| `partOf` | match → tournament | is part of | not part of | The tournament edition the match belonged to. Friendlies have none. |
| `had` | match → goal | had | had no | Goals in the match, where scorers were recorded. |
| `wonBy` | tournament → team | was won by | not won by | The winner of the final, counting penalties. Empty for league-format tournaments and qualifying. |
| `scoredIn` | goal → match | was scored in | not scored in | gives the child a team in focus. The match the goal was scored in, seen from the side it counted for. |
| `countedFor` | goal → team | counted for | didn't count for | An own goal counts for the opposition. |
| `contains` | streak → match | contains | doesn't contain | gives the child a team in focus. mode must stay required. The matches inside the run, one row per match, in date order. |
| `scored` | player → goal | scored | never scored | Every goal with their name on it, own goals included — filter on Own goal to leave them out. |
| `playerScoredIn` | player → match | scored in | never scored in | gives the child a team in focus. Matches with at least one of their goals, with their side in focus — so Result is their team's result. |
| `playedFor` | player → team | played for | didn't play for | The national side they played for. |
| `scoredBy` | goal → player | was scored by | not scored by | The player who scored it — for an own goal, a player on the other side. |
| `sideOf` | match → team | from the side of |  | mode must stay required. Puts one side in focus, so Result, Goals for and Opponent are from its side. Both sides are tried; this block's conditions pick which — so England v Germany appears twice if both sides qualify. |
| `facedIn` | team → match | was the opponent in | was never the opponent in | gives the child a team in focus. Matches it played, seen from the other side — Result is the opponent's. The reverse of played against. |
| `goalsFor` | match → goal | they scored | they didn't score | needs the parent match to have a team in focus. Goals that counted for the team in focus — opponents' own goals included. Had lists both sides' goals. |
| `inMatch` | goal → match | came in | didn't come in | The match the goal came in, with no team in focus. Was scored in puts the goal's side in focus instead. |
| `matchScorers` | match → player | had scorer | had no scorer | Players with a goal in it, own goals aside. With a team in focus, only that side's scorers. |
| `tournamentMatches` | tournament → match | included | didn't include | Every match in the edition, from neither side. |
| `won` | team → tournament | won | never won | gives the child a team in focus. Editions whose final it won, counting penalties. League-format tournaments and qualifying have no winner. |
| `featured` | tournament → team | featured | didn't feature | Sides with at least one match in the edition. |
| `teamGoals` | team → goal | scored | never scored | Goals that counted for it, where the scorer was recorded — opponents' own goals included. |
| `teamScorers` | team → player | had scorer | had no scorer | Players who scored for it at least once. |
| `teamPlayers` | team → player | had player | had no player | Everyone on record for it — in a line-up, on the scoresheet or booked. The reverse of played for. |
| `appearedIn` | player → match | played in | never played in | gives the child a team in focus. Matches with them in the recorded line-up — started, or came on — with their side in focus. Only where line-ups are known. |
| `startedIn` | player → match | started | never started | gives the child a team in focus. Matches they started, with their side in focus. |
| `cameOnIn` | player → match | came on in | never came on in | gives the child a team in focus. Matches they came on in as a substitute, with their side in focus. |
| `lineup` | match → player | had in its line-up | didn't have in its line-up | Everyone who played — starters and substitutes who came on. With a team in focus, only that side's players. |
| `hadCard` | match → card | had card | had no card | Cards shown in the match, where cards are known. With a team in focus, only its players' cards. |
| `shownIn` | card → match | was shown in | not shown in | gives the child a team in focus. The match, seen from the booked player's side. |
| `received` | player → card | received | never received | Every card shown to them, where cards are known. |
| `shownTo` | card → player | was shown to | not shown to | The player it was shown to. |
| `teamCards` | team → card | was shown | was never shown | Cards shown to its players. |
| `cardTeam` | card → team | was shown to a player of | not shown to a player of | The booked player's national side. |
| `playerAppearances` | player → appearance | made appearance | never made appearance | Each match they played, as an appearance: minutes, goals, cards, position, debut. |
| `appearanceBy` | appearance → player | was made by | not made by | The player who made it. |
| `appearanceIn` | appearance → match | was in | not in | gives the child a team in focus. The match, with the player's side in focus. |
| `matchAppearances` | match → appearance | had appearance | had no appearance | Everyone who played in it, as appearances. With a team in focus, only its side. |
| `teamAppearances` | team → appearance | had appearance | had no appearance | Every appearance for it — sum minutes or count by player. |
| `appearanceTeam` | appearance → team | was for | not for | The side they played for. |
| `playedAlongside` | player → player | played alongside | never played alongside | puts the parent player in focus for the child (Matches shared, Pair…). Team-mates who were in the same recorded line-up. Adds Matches shared, Starts shared and Pair — group by Pair for the most-used partnerships. |
| `playedAgainstPlayer` | player → player | played against | never played against | puts the parent player in focus for the child (Matches shared, Pair…). Players on the other side in a recorded line-up. Adds Matches shared and Shared matches won. |
| `playerRun` | player → streak | has a run of |  | A player's runs: consecutive appearances, starts or full matches in their side's matches, or consecutive appearances with a goal. |
| `nextMatch` | match → match | was followed by | was never followed by | gives the child a team in focus. needs the parent match to have a team in focus. The team in focus's next match — e.g. how sides did after a 5-goal defeat. |
| `previousMatch` | match → match | came after | didn't come after | gives the child a team in focus. needs the parent match to have a team in focus. The team in focus's previous match. |
| `nextEdition` | tournament → tournament | next edition | had no next edition | gives the child a team in focus. The next edition of the same competition. The team in focus carries over — so winners, then next edition where Finish is Group stage, finds defending champions out early. |
| `previousEdition` | tournament → tournament | previous edition | had no previous edition | gives the child a team in focus. The previous edition of the same competition, keeping the team in focus. |
| `containsEditions` | streak → tournament | contains |  | gives the child a team in focus. mode must stay required. The editions inside a run of editions, one row each, in order. |

## Properties

Refer to a property in a column ref as `<blockId>.<key>`, and in a condition by `key` alone (it applies to the block the condition sits in).

### Team (`team`)

| key | label on canvas | type | notes |
|---|---|---|---|
| `name` | Name | ref (names of: team) | The side's current name. Historical sides are merged into their successor. |
| `confederation` | Confederation | enum (AFC, CAF, CONCACAF, CONMEBOL, OFC, UEFA) | UEFA, CONMEBOL, CONCACAF, CAF, AFC or OFC — inferred from the continental competitions a side enters. |
| `played` | Played | number | Matches played, all time. |
| `won` | Won | number | Matches won, all time. A shootout counts as a draw. |
| `drawn` | Drawn | number | Matches drawn, all time, shootouts included. |
| `lost` | Lost | number | Matches lost, all time. |
| `winPct` | Win % | number | Share of matches won, all time. |
| `goalsFor` | Goals for | number | Goals scored, all time. |
| `goalsAgainst` | Goals against | number | Goals conceded, all time. |
| `goalDifference` | Goal difference | number | Goals for minus goals against, all time. |
| `firstMatch` | First match | date | Date of the side's first recorded match. |
| `lastMatch` | Last match | date | Date of its most recent match. |
| `lastWin` | Last win | date | Date of its most recent win. "More than 3 years ago" finds long droughts. |
| `titles` | Titles | number | Tournament finals it won, any competition. |
| `worldCupTitles` | World Cup titles | number | World Cups won. |
| `elo` | Elo rating now | number | Current World Football Elo rating — today's, not at the time of any match (for that, use a match's Elo at kick-off), worked out from every result here: 1500 to start, more for big wins in big matches. |
| `peakElo` | Peak Elo | number | Its highest Elo rating ever. |
| `peakEloDate` | Peak Elo date | date | When it reached its peak rating. |
| `self` | Team | ref | Only with an alias value. The same team as the block the alias names. |

### Match (`match`)

| key | label on canvas | type | notes |
|---|---|---|---|
| `date` | Date | date | When it was played. |
| `year` | Year | number | Calendar year it was played. |
| `competition` | Competition | ref (names of: competition) | World Cup, Copa América, Friendly… |
| `competitionType` | Competition type | enum (Finals, Qualification, Friendly) | Finals, Qualification or Friendly. Invitation series count as friendlies. |
| `tournament` | Tournament | ref (names of: tournament) | The edition, e.g. FIFA World Cup 2014. Friendlies have none. |
| `stage` | Stage | ref (names of: stage) | Group stage, Round of 16, Quarter-final, Semi-final, Third-place play-off, Final… |
| `group` | Group | ref (names of: group) | Group A, Group B… where there is one. |
| `knockout` | Knockout | bool | A knockout round rather than a group or league round. |
| `team1` | Team 1 | ref (names of: team) | The first side as the source lists it. |
| `team2` | Team 2 | ref (names of: team) | The second side as the source lists it. |
| `label` | Match | text | Column only (not filterable). Both sides and the score, e.g. Brazil 2–0 Serbia. |
| `score` | Score | text | Column only (not filterable). After extra time, e.g. 4–2. Under a team, that team's goals come first. |
| `totalGoals` | Total goals | number | Goals by both sides, after extra time. |
| `margin` | Margin | number | Absolute goal difference, after extra time. |
| `endedLevel` | Ended level | bool | Level after extra time — a draw under Result, shootout or not. |
| `wentToPenalties` | Went to penalties | bool | Decided by a shootout. |
| `penaltyWinner` | Penalty winner | ref (names of: team) | The side that won the shootout. |
| `wentToExtraTime` | Went to extra time | tri | Inferred from a goal after 90' or a shootout. Unknown where scorers weren't recorded. |
| `venueCity` | Venue city | ref (names of: city) | Where it was played. |
| `venueCountry` | Venue country | ref (names of: country) | The country it was played in. |
| `neutralVenue` | Neutral venue | bool | Played in a country that was neither side's. |
| `hatTrick` | Had a hat-trick | bool | A player scored three or more (own goals excluded). |
| `hatTrickScorers` | Hat-trick scorers | text | Who scored three or more. |
| `scorers` | Scorers | refMulti (names of: player) | Everyone with a goal in it, own goals aside. |
| `fixture` | Fixture | text | Both sides in alphabetical order — England v Germany however the source lists it. Group by it for the most-played fixture. |
| `winner` | Winner | ref (names of: team) | The side that won after extra time. Empty for a draw. |
| `loser` | Loser | ref (names of: team) | The side that lost after extra time. |
| `winnerPens` | Winner incl. penalties | ref (names of: team) | The side that went through, shootouts included. |
| `leadChanges` | Lead changes | number | Times the lead passed from one side to the other. Only where every goal has a scorer. |
| `winningGoalMinute` | Winning goal minute | number | When the goal that decided it went in — the winner's goal that put them ahead for good. Only where every goal has a scorer. |
| `comeback` | Comeback | tri | The winner was behind at some point. Unknown where not every goal has a scorer. |
| `team1Elo` | Team 1 Elo at kick-off | number | Team 1's World Football Elo rating going into the match. |
| `team2Elo` | Team 2 Elo at kick-off | number | Team 2's World Football Elo rating going into the match. |
| `eloGap` | Elo gap | number | Difference between the two sides' Elo ratings before kick-off. |
| `scorersKnown` | Scorers complete | bool | Every goal has a named scorer. |
| `lineupsKnown` | Line-ups known | bool | Both sides' line-ups are recorded (starters and substitutes who came on). |
| `cardsKnown` | Cards known | bool | The cards shown are recorded — a match with none known to have none counts. |
| `yellowCards` | Yellow cards | number | Yellow cards shown to both sides, second yellows included. Empty where cards aren't known. |
| `redCards` | Sendings-off | number | Players sent off, by a red or a second yellow. Empty where cards aren't known. |
| `cards` | Cards shown | number | Every card, yellow or red, to both sides. Empty where cards aren't known. |
| `scorersFrom` | Scorers from | enum (openfootball, martj42, Fjelstul, ESPN, none) | Which source named the scorers: openfootball, martj42, Fjelstul (World Cups), ESPN — or none. |
| `lineupsFrom` | Line-ups from | enum (openfootball, martj42, Fjelstul, ESPN, none) | Which source has the line-ups — Fjelstul (World Cups since 1970) or ESPN — or none. |
| `cardsFrom` | Cards from | enum (openfootball, martj42, Fjelstul, ESPN, none) | Which source has the cards — Fjelstul or ESPN — or none. |
| `upset` | Upset | tri | The lower-rated side (by Elo, before kick-off) won. Unknown for a draw. |
| `team` | Team | ref (names of: team) | **Team in focus only.** Column only (not filterable). The team in focus. |
| `result` | Result | enum (Win, Draw, Loss) | **Team in focus only.** Win, Draw or Loss for the team in focus. A shootout counts as a draw. |
| `resultPens` | Result incl. penalties | enum (Win, Draw, Loss) | **Team in focus only.** As Result, but a shootout counts for whoever went through. |
| `opponent` | Opponent | ref (names of: team) | **Team in focus only.** The side the team in focus faced. |
| `goalsFor` | Goals for | number | **Team in focus only.** Goals by the team in focus, after extra time. |
| `goalsAgainst` | Goals against | number | **Team in focus only.** Goals conceded by the team in focus. |
| `goalDifference` | Goal difference | number | **Team in focus only.** Signed: goals for minus goals against. |
| `cleanSheet` | Clean sheet | bool | **Team in focus only.** The team in focus conceded nothing. |
| `scored` | Scored | bool | **Team in focus only.** The team in focus scored at least once. |
| `ground` | Ground | enum (Home, Away, Neutral) | **Team in focus only.** Home, Away or Neutral for the team in focus. |
| `scoredFirst` | Scored first | tri | **Team in focus only.** The team in focus opened the scoring. Unknown where not every goal has a scorer. |
| `trailed` | Trailed | tri | **Team in focus only.** The team in focus was behind at some point. |
| `led` | Led | tri | **Team in focus only.** The team in focus was ahead at some point. |
| `maxDeficit` | Biggest deficit | number | **Team in focus only.** Most goals the team in focus was behind by. |
| `cameFromBehind` | Came from behind to win | tri | **Team in focus only.** Trailed, then won. |
| `scorersFor` | Scorers for | refMulti (names of: player) | **Team in focus only.** The team in focus's scorers in it — e.g. includes Kylian Mbappé. |
| `teamYellowCards` | Yellow cards (theirs) | number | **Team in focus only.** Yellow cards shown to the team in focus. Empty where cards aren't known. |
| `teamRedCards` | Sent off (theirs) | number | **Team in focus only.** Players of the team in focus sent off. |
| `opponentRedCards` | Opponents sent off | number | **Team in focus only.** Players of the opponent sent off. |
| `startingXICaps` | Starting XI's caps | number | **Team in focus only.** Recorded caps the team in focus's starters had between them before kick-off — how experienced the side was. A lower bound, like every cap count. |
| `lineupChanges` | Changes to the XI | number | **Team in focus only.** Starters who didn't start the team in focus's previous match. Empty unless both line-ups are known. |
| `elo` | Elo at kick-off | number | **Team in focus only.** The team in focus's Elo rating going into the match — at the time, not today's. |
| `opponentElo` | Opponent Elo at kick-off | number | **Team in focus only.** The opponent's Elo rating going into the match. |
| `eloAfter` | Elo after | number | **Team in focus only.** The team in focus's Elo rating once the result was counted. |
| `eloDiff` | Elo difference | number | **Team in focus only.** Team in focus minus opponent, before kick-off — negative when it was the underdog. |
| `eloChange` | Elo change | number | **Team in focus only.** Rating points the team in focus gained or lost. |
| `winChance` | Expected score | number | **Team in focus only.** Elo's expectation for the team in focus before kick-off, as a percentage (a draw counts half), home advantage included. |
| `daysSincePrevious` | Days since previous match | number | **Team in focus only.** Days since the team in focus last played. |
| `daysUntilNext` | Days until next match | number | **Team in focus only.** Days until the team in focus played again. Empty for its latest match. |
| `self` | Match | ref | Only with an alias value. The same match as the block the alias names. |

### Tournament (`tournament`)

| key | label on canvas | type | notes |
|---|---|---|---|
| `name` | Name | ref (names of: tournament) | The edition, e.g. FIFA World Cup 2014. |
| `competition` | Competition | ref (names of: competition) | Which competition it's an edition of. |
| `competitionType` | Competition type | enum (Finals, Qualification, Friendly) | Finals, Qualification or Friendly. |
| `year` | Year | number | The edition's name year — Euro 2020 is 2020 though it was played in 2021. |
| `startDate` | Start date | date | First match. |
| `endDate` | End date | date | Last match. |
| `hostCountries` | Host countries | refMulti (names of: country) | Countries matches were played in — finals tournaments only. |
| `teams` | Teams | number | Sides that took part. |
| `matches` | Matches | number | Matches played. |
| `winner` | Winner | ref (names of: team) | Winner of the final, counting penalties. Empty for league-format tournaments. |
| `heldUntil` | Title held until | date | When the winner's reign ended: the end of the next edition. For the current holder, the latest date in the data; empty for a competition no longer played, and without a winner. A title's reign runs from its End date to this — two overlap when each starts before the other ends. |
| `finish` | Finish | enum (Winner, Runner-up, Third place, Fourth place, Semi-finals, Quarter-finals, Second group stage, Final round, Round of 16, Group stage) | **Team in focus only.** How far the team in focus got: Winner, Runner-up, Third place… Group stage. Only for finals whose stages the source names. |
| `finishRank` | Finish rank | number | **Team in focus only.** The finish as a number, 1 for the winner — lower is better. Rank or sort by it for a team's best showing. |
| `teamPlayed` | Played there | number | **Team in focus only.** Matches the team in focus played at this tournament. |
| `teamWon` | Won there | number | **Team in focus only.** Its wins at this tournament. |
| `teamDrawn` | Drawn there | number | **Team in focus only.** Its draws at this tournament. |
| `teamLost` | Lost there | number | **Team in focus only.** Its defeats at this tournament. |
| `teamGoalsFor` | Goals for there | number | **Team in focus only.** Its goals at this tournament. |
| `teamGoalsAgainst` | Goals against there | number | **Team in focus only.** Goals it conceded at this tournament. |
| `group` | Group | text | **Team in focus only.** Its group, where there were groups. |
| `groupPosition` | Group position | number | **Team in focus only.** Where it finished in its group: points, then goal difference, then goals. Head-to-head tie-breaks and lots aren't applied. |
| `groupPoints` | Group points | number | **Team in focus only.** Its group-stage points — two for a win before 1995, three after. |
| `gapYears` | Years since last appearance | number | **Team in focus only.** Years back to its previous edition of this competition. Empty for a debut. |
| `titleGap` | Years since last title | number | **Team in focus only.** For a title: years since its previous title in this competition. Empty for a first. |
| `self` | Tournament | ref | Only with an alias value. The same tournament as the block the alias names. |

### Goal (`goal`)

| key | label on canvas | type | notes |
|---|---|---|---|
| `scorer` | Scorer | text (names of: player) | The scorer's name as recorded. Type to see matching players. |
| `minute` | Minute | number | Minute of the goal. Stoppage time is recorded as the 45th or 90th minute. |
| `penalty` | Penalty | bool | Scored from the spot. |
| `ownGoal` | Own goal | bool | An own goal, counted for the opposition. |
| `inExtraTime` | In extra time | bool | Minute after 90. |
| `date` | Date | date | Date of the match. |
| `tournament` | Tournament | ref (names of: tournament) | The edition it came in, e.g. FIFA World Cup 2014. Count it distinct for the number of tournaments a player scored at. |
| `year` | Year | number | Calendar year of the match. |
| `competition` | Competition | ref (names of: competition) | Competition of the match. |
| `team` | Scored for | ref (names of: team) | The side the goal counted for. |
| `opponent` | Against | ref (names of: team) | The side it was scored against. |
| `match` | Match | text | Column only (not filterable). The match, e.g. Brazil 2–0 Serbia. |
| `role` | Role | enum (Opening goal, Equaliser, Go-ahead goal, Winning goal, Extended lead, Pulled one back) | What it did: Opening goal, Equaliser, Go-ahead goal, Winning goal (put the winner ahead for good), Extended lead, Pulled one back. Only where every goal in the match has a scorer. |
| `winningGoal` | Winning goal | tri | The goal that put the eventual winner ahead for good. |
| `scoreAfter` | Score after | text | The score just after it, scoring side first — e.g. 2–1. |
| `sincePrevious` | Years since their previous goal | number | The wait since the same player's last recorded goal, own goals aside. Empty for a first goal. Older friendlies mostly have no scorers, so a wait can hide goals in them. |
| `number` | Goal number | number | Its place among the match's goals, in minute order. |
| `competitionType` | Competition type | enum (Finals, Qualification, Friendly) | Finals, Qualification or Friendly. |
| `bySubstitute` | Scored by a substitute | tri | The scorer came off the bench. Unknown where the line-up isn't known. |
| `afterComingOn` | Minutes after coming on | number | For a substitute's goal: minutes between coming on and scoring. |
| `onDebut` | On debut | tri | Scored in the scorer's first cap — known only where the side's line-ups go back two years unbroken. |
| `scorerPosition` | Scorer's position | enum (Goalkeeper, Defender, Midfielder, Forward) | Goalkeeper, Defender, Midfielder or Forward: where the scorer usually lined up. |
| `self` | Goal | ref | Only with an alias value. The same goal as the block the alias names. |

### Player (`player`)

| key | label on canvas | type | notes |
|---|---|---|---|
| `name` | Name | text (names of: player) | The name as the sources spell it — a line-up's spelling first. Type to see matching players. |
| `team` | Played for | ref (names of: team) | Their national side. Someone who switched nations is two players here. |
| `caps` | Caps | number | Matches in a recorded line-up, as a starter or a substitute who came on. A lower bound: line-ups are known for World Cups since 1970, most competitive matches since about 2003 and friendlies since about 2016. |
| `starts` | Starts | number | Recorded matches they started. |
| `subAppearances` | Substitute appearances | number | Recorded matches they came on in. |
| `yellowCards` | Yellow cards | number | Yellow cards on record (a second yellow counts as a sending-off instead). |
| `redCards` | Sendings-off | number | Straight reds and second yellows on record. |
| `position` | Position | enum (Goalkeeper, Defender, Midfielder, Forward) | Where they usually lined up: Goalkeeper, Defender, Midfielder or Forward. From the positions sources give; substitutes often have none. |
| `minutes` | Minutes played | number | Minutes over their recorded appearances: to the final whistle, being taken off or being sent off. |
| `minutesPerGoal` | Minutes per goal | number | Minutes played for each goal scored in their recorded appearances. |
| `won` | Won (when playing) | number | Matches their side won with them in the line-up. A shootout counts as a draw. |
| `drawn` | Drawn (when playing) | number | Matches drawn with them in the line-up. |
| `lost` | Lost (when playing) | number | Matches lost with them in the line-up. |
| `winPct` | Win % when playing | number | Share of their recorded appearances their side won. |
| `cleanSheets` | Clean sheets | number | Matches they started and played to the end without their side conceding — for goalkeepers, their clean sheets. |
| `firstCap` | First recorded cap | date | Their first match in a recorded line-up. |
| `lastCap` | Last recorded cap | date | Their latest match in a recorded line-up. |
| `firstSeen` | First on record | date | Their first match with anything of theirs on record: a line-up, a goal or a card. |
| `lastSeen` | Last on record | date | Their latest match with anything of theirs on record. |
| `goals` | Goals | number | Goals for their side with a recorded scorer — a lower bound, since older friendlies mostly have none. |
| `penalties` | Penalties | number | Goals from the spot. |
| `ownGoals` | Own goals | number | Own goals — not included in Goals. |
| `hatTricks` | Hat-tricks | number | Matches with three or more of their goals. |
| `matchesScoredIn` | Matches scored in | number | Matches with at least one of their goals. |
| `firstGoal` | First goal | date | Date of their first recorded goal. |
| `lastGoal` | Last goal | date | Date of their most recent recorded goal. |
| `longestGap` | Longest gap between goals (years) | number | Their longest wait between two recorded goals. Gaps over 20 years are read as two people of the same name, so they never appear here. |
| `namesakeSplit` | Split from a namesake | bool | The same name was on record for the same side more than 20 years before them, with nothing in between — taken here to be a different person. |
| `careerYears` | Scoring span (years) | number | Years from first to last recorded goal. |
| `sharedMatches` | Matches shared | number | **Only on a player reached by played alongside / against.** Matches both played in — together, under played alongside; on opposite sides, under played against. |
| `sharedStarts` | Starts shared | number | **Only on a player reached by played alongside / against.** Matches both started. |
| `sharedWins` | Shared matches won | number | **Only on a player reached by played alongside / against.** Of the matches shared, those this player's side won. |
| `pair` | Pair | text | **Only on a player reached by played alongside / against.** Column only (not filterable). Both players, in alphabetical order — group by it so each pair counts once, whichever way round it was reached. |
| `self` | Player | ref | Only with an alias value. The same player as the block the alias names. |

### Card (`card`)

| key | label on canvas | type | notes |
|---|---|---|---|
| `player` | Player | text (names of: player) | Who was shown it. Type to see matching players. |
| `kind` | Card | enum (Yellow, Second yellow, Red) | Yellow, Second yellow (a sending-off) or Red. |
| `sendingOff` | Sending-off | bool | A red or a second yellow. |
| `minute` | Minute | number | When it was shown. Stoppage time counts as the 45th or 90th minute; empty where the source counts the card without timing it. |
| `team` | Team | ref (names of: team) | The booked player's side. |
| `opponent` | Against | ref (names of: team) | The side they were playing. |
| `date` | Date | date | Date of the match. |
| `year` | Year | number | Calendar year of the match. |
| `competition` | Competition | ref (names of: competition) | Competition of the match. |
| `tournament` | Tournament | ref (names of: tournament) | The edition it came in. |
| `match` | Match | text | Column only (not filterable). The match, e.g. Brazil 2–0 Serbia. |
| `competitionType` | Competition type | enum (Finals, Qualification, Friendly) | Finals, Qualification or Friendly. |
| `bySubstitute` | Shown to a substitute | tri | The player had come off the bench. Unknown where the line-up isn't known. |
| `afterComingOn` | Minutes after coming on | number | For a substitute: minutes between coming on and being shown it. |
| `self` | Card | ref | Only with an alias value. The same card as the block the alias names. |

### Appearance (`appearance`)

| key | label on canvas | type | notes |
|---|---|---|---|
| `player` | Player | text (names of: player) | Who played. Type to see matching players. |
| `team` | Team | ref (names of: team) | Their side. |
| `opponent` | Against | ref (names of: team) | The side they played. |
| `date` | Date | date | Date of the match. |
| `year` | Year | number | Calendar year of the match. |
| `competition` | Competition | ref (names of: competition) | Competition of the match. |
| `competitionType` | Competition type | enum (Finals, Qualification, Friendly) | Finals, Qualification or Friendly. |
| `tournament` | Tournament | ref (names of: tournament) | The edition it came in. Count it distinct for the number of tournaments played at. |
| `stage` | Stage | ref (names of: stage) | Group stage, Final… |
| `match` | Match | text | Column only (not filterable). The match, e.g. Brazil 2–0 Serbia. |
| `score` | Score | text | Column only (not filterable). Their side's goals first. |
| `result` | Result | enum (Win, Draw, Loss) | Win, Draw or Loss for their side. A shootout counts as a draw. |
| `started` | Started | bool | In the starting XI — no means they came on. |
| `position` | Position | enum (Goalkeeper, Defender, Midfielder, Forward) | Where they lined up. Substitutes often have none. |
| `shirt` | Shirt number | number | The number they wore. |
| `cameOn` | Came on | number | For a substitute: the minute they came on. |
| `wentOff` | Taken off | number | The minute they were substituted. Empty if they weren't. |
| `subbedOff` | Substituted | bool | Taken off before the end. |
| `minutes` | Minutes | number | Minutes on the pitch: to the final whistle (90, or 120 after extra time), being taken off or being sent off. |
| `fullMatch` | Played the whole match | bool | Started and was neither taken off nor sent off. |
| `goals` | Goals | number | Their goals in the match, own goals aside. Where scorers aren't all known, a lower bound. |
| `scored` | Scored | bool | Scored at least once. |
| `booked` | Booked | bool | Shown a yellow card. |
| `sentOff` | Sent off | bool | A red card or a second yellow. |
| `capNumber` | Recorded cap number | number | Its place among the player's recorded appearances — 1 for the first on record, which isn't always their debut. |
| `debut` | Debut | tri | Their first cap: known only where the side's line-ups go back two years unbroken, so an earlier cap can't be missing. |
| `self` | Appearance | ref | Only with an alias value. The same appearance as the block the alias names. |

### Streak (`streak`)

| key | label on canvas | type | notes |
|---|---|---|---|
| `kind` | Kind | text | Column only (not filterable). What the run is of, and across which matches. |
| `team` | Team | ref (names of: team) | Column only (not filterable). The side with the run. |
| `player` | Player | text | Column only (not filterable). For a player's run: the player. |
| `length` | Length | number | Matches in the run. |
| `startDate` | Start date | date | Date of the first match in the run. |
| `endDate` | End date | date | Date of the last match in the run. |
| `isActive` | Is active | bool | Still going: the run includes the team's latest match in scope (for a player, nothing has broken it since their side's latest known line-up). |
| `isMostRecent` | Is most recent | bool | The most recent of the streaks that pass this block's other conditions — so with Length > 8 it finds the most recent run over 8, never nothing. |
| `endedBy` | Ended by | ref (names of: team) | The opponent in the match that broke the run. Empty while active. |
| `goalsFor` | Goals for | number | Goals scored during the run. |
| `goalsAgainst` | Goals against | number | Goals conceded during the run. |
| `days` | Duration (days) | number | Days from the first match (or edition) of the run to the last. |

## Operators by property type

| property type | operators |
|---|---|
| text | `contains` (contains), `startsWith` (starts with), `is` (is) |
| ref | `is` (is), `isNot` (is not), `anyOf` (is any of) |
| refMulti | `includes` (includes), `anyOf` (is any of) |
| enum | `is` (is), `isNot` (is not), `anyOf` (is any of) |
| number | `gt` (>), `gte` (≥), `lt` (<), `lte` (≤), `eq` (=), `ne` (≠), `between` (between) |
| date | `after` (after), `before` (before), `on` (on), `between` (between), `inYear` (in year), `inDecade` (in decade), `inLast` (in the last), `notInLast` (more than … ago), `thisYear` (this year), `thisDecade` (this decade) |
| bool | `is` (is) |
| tri | `is` (is) |

Value formats: dates are ISO `YYYY-MM-DD` strings; `between` takes `[from, to]`; `inYear` a number; `inDecade` a year like 1990; `inLast` / `notInLast` `{ amount, unit }`; `anyOf` an array; `bool` true/false; `tri` true/false/"unknown".

## Streaks

Conditions over matches:
- `wins` — Consecutive matches won.
- `winsPens` — As Wins, but a match won on penalties keeps the run going.
- `unbeaten` — No defeat. A draw — shootouts included — keeps it going.
- `draws` — Consecutive draws.
- `losses` — Consecutive defeats.
- `winless` — No win — draws and defeats both continue it.
- `cleanSheets` — Matches without conceding.
- `scored` — Matches with at least one goal.
- `failedToScore` — Matches without a goal.
- `custom` — `conditionItems` (match conditions, team in focus).

Conditions over editions (`over: "editions"`, `scope: "competition"`, `competitions: ["FIFA World Cup"]`):
- `entered` — Played at the finals — consecutive appearances.
- `champion` — Won the edition — back-to-back titles.
- `reachedFinal` — Winner or runner-up.
- `reachedSemis` — Top four.
- `pastGroups` — Reached the knockout rounds. Editions whose stages the source doesn't name count as not.
- `custom` — `conditionItems` (tournament conditions, team in focus; the team must have taken part).

Scopes (which matches make up the sequence — others neither extend nor break a run):
- `all` — Every match, friendlies included.
- `competitive` — Finals and qualifying. Friendlies and invitation series don't count — and don't break the run either.
- `finals` — Finals of official competitions only.
- `competition` — only matches in `competitions`.
- `custom` — only matches passing `scopeItems`.

A player's runs (`playerRun`, player → streak) take these conditions, with scope `all`, `competitive`, `finals` or `competition`:
- `appeared` — Played in each of their side's matches in turn. Matches whose line-ups aren't known are skipped — they neither count nor break the run.
- `started` — Started each of their side's matches in turn — line-ups unknown are skipped.
- `fullMatches` — Played every minute of each of their side's matches in turn — line-ups unknown are skipped.
- `scoredApps` — Scored in each of their own appearances in turn. Only matches where every goal's scorer is known count.

Streak properties: kind, team, player (for a player's run), length, startDate, endDate, isActive, isMostRecent, endedBy, goalsFor, goalsAgainst, days. Relation `contains` (streak → match) or `containsEditions` (streak → tournament) lists the members.

## Named counts (measures)

- Wins: `{ "fn": "countWhere", "where": { "property": "result", "op": "is", "value": "Win" } }`
- Draws: `{ "fn": "countWhere", "where": { "property": "result", "op": "is", "value": "Draw" } }`
- Losses: `{ "fn": "countWhere", "where": { "property": "result", "op": "is", "value": "Loss" } }`
- Wins incl. penalties: `{ "fn": "countWhere", "where": { "property": "resultPens", "op": "is", "value": "Win" } }`
- Clean sheets: `{ "fn": "countWhere", "where": { "property": "cleanSheet", "op": "is", "value": true } }`
- Shootouts: `{ "fn": "countWhere", "where": { "property": "wentToPenalties", "op": "is", "value": true } }`
- Penalties: `{ "fn": "countWhere", "where": { "property": "penalty", "op": "is", "value": true } }`
- Own goals: `{ "fn": "countWhere", "where": { "property": "ownGoal", "op": "is", "value": true } }`

## Worked examples

### Every England v Germany match
Question: How many times have England and Germany played each other?
Teaches: Two sibling blocks under one match — each must hold, so the match involves both sides.
Reads as: Find matches, played by England, played by Germany.
On the canvas:
```
FIND Match
  THAT played by Team  [hidden]
    WHERE Name is "England"
  THAT played by Team  [hidden]
    WHERE Name is "Germany"
```
```json
{
  "query": {
    "v": 1,
    "root": {
      "id": "mt",
      "entity": "match",
      "relation": null,
      "join": "and",
      "items": [],
      "shown": true,
      "children": [
        {
          "id": "eng",
          "entity": "team",
          "relation": "playedBy",
          "join": "and",
          "items": [
            {
              "id": "c1",
              "kind": "cond",
              "property": "name",
              "op": "is",
              "value": "England"
            }
          ],
          "shown": false,
          "children": []
        },
        {
          "id": "ger",
          "entity": "team",
          "relation": "playedBy",
          "join": "and",
          "items": [
            {
              "id": "c2",
              "kind": "cond",
              "property": "name",
              "op": "is",
              "value": "Germany"
            }
          ],
          "shown": false,
          "children": []
        }
      ]
    },
    "grouping": null,
    "ranking": null
  }
}
```
Link: https://fq.rking.ie/?q=%7B%22q%22%3A%7B%22v%22%3A1%2C%22root%22%3A%7B%22id%22%3A%22mt%22%2C%22entity%22%3A%22match%22%2C%22relation%22%3Anull%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%7B%22id%22%3A%22eng%22%2C%22entity%22%3A%22team%22%2C%22relation%22%3A%22playedBy%22%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c1%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22name%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22England%22%7D%5D%2C%22shown%22%3Afalse%2C%22children%22%3A%5B%5D%7D%2C%7B%22id%22%3A%22ger%22%2C%22entity%22%3A%22team%22%2C%22relation%22%3A%22playedBy%22%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c2%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22name%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22Germany%22%7D%5D%2C%22shown%22%3Afalse%2C%22children%22%3A%5B%5D%7D%5D%7D%2C%22grouping%22%3Anull%2C%22ranking%22%3Anull%7D%7D
Expected answer: 35 matches, from 1930 to 2022. West Germany's matches count as Germany's.

### Brazil's World Cup wins
Question: Which World Cup matches have Brazil won?
Teaches: A match reached from a team has that team in focus, so Result, Opponent and Goals for are Brazil's.
Reads as: Find Brazil, that played matches where result is Win and competition is FIFA World Cup.
On the canvas:
```
FIND Team  [hidden]
  WHERE Name is "Brazil"
  THAT played Match
    WHERE Result is Win
    AND Competition is "FIFA World Cup"
```
```json
{
  "query": {
    "v": 1,
    "root": {
      "id": "t",
      "entity": "team",
      "relation": null,
      "join": "and",
      "items": [
        {
          "id": "c1",
          "kind": "cond",
          "property": "name",
          "op": "is",
          "value": "Brazil"
        }
      ],
      "shown": false,
      "children": [
        {
          "id": "mt",
          "entity": "match",
          "relation": "played",
          "join": "and",
          "items": [
            {
              "id": "c2",
              "kind": "cond",
              "property": "result",
              "op": "is",
              "value": "Win"
            },
            {
              "id": "c3",
              "kind": "cond",
              "property": "competition",
              "op": "is",
              "value": "FIFA World Cup"
            }
          ],
          "shown": true,
          "children": []
        }
      ]
    },
    "grouping": null,
    "ranking": null
  }
}
```
Link: https://fq.rking.ie/?q=%7B%22q%22%3A%7B%22v%22%3A1%2C%22root%22%3A%7B%22id%22%3A%22t%22%2C%22entity%22%3A%22team%22%2C%22relation%22%3Anull%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c1%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22name%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22Brazil%22%7D%5D%2C%22shown%22%3Afalse%2C%22children%22%3A%5B%7B%22id%22%3A%22mt%22%2C%22entity%22%3A%22match%22%2C%22relation%22%3A%22played%22%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c2%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22result%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22Win%22%7D%2C%7B%22id%22%3A%22c3%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22competition%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22FIFA%20World%20Cup%22%7D%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%5D%7D%5D%7D%2C%22grouping%22%3Anull%2C%22ranking%22%3Anull%7D%7D
Expected answer: 79 matches, the latest three at the 2026 World Cup.

### Teams that have never played at a World Cup
Question: Which sides have never played a World Cup finals match?
Teaches: A negated relation keeps only the parents with no match. It filters, so it's hidden.
Reads as: Find teams, that never played matches where competition is FIFA World Cup.
On the canvas:
```
FIND Team
  THAT never played Match
    WHERE Competition is "FIFA World Cup"
```
```json
{
  "query": {
    "v": 1,
    "root": {
      "id": "t",
      "entity": "team",
      "relation": null,
      "join": "and",
      "items": [],
      "shown": true,
      "children": [
        {
          "id": "mt",
          "entity": "match",
          "relation": "played",
          "join": "and",
          "items": [
            {
              "id": "c1",
              "kind": "cond",
              "property": "competition",
              "op": "is",
              "value": "FIFA World Cup"
            }
          ],
          "shown": false,
          "children": [],
          "mode": "without"
        }
      ]
    },
    "grouping": null,
    "ranking": null
  }
}
```
Link: https://fq.rking.ie/?q=%7B%22q%22%3A%7B%22v%22%3A1%2C%22root%22%3A%7B%22id%22%3A%22t%22%2C%22entity%22%3A%22team%22%2C%22relation%22%3Anull%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%7B%22id%22%3A%22mt%22%2C%22entity%22%3A%22match%22%2C%22relation%22%3A%22played%22%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c1%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22competition%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22FIFA%20World%20Cup%22%7D%5D%2C%22shown%22%3Afalse%2C%22children%22%3A%5B%5D%2C%22mode%22%3A%22without%22%7D%5D%7D%2C%22grouping%22%3Anull%2C%22ranking%22%3Anull%7D%7D
Expected answer: 131 of the 215 teams — Cape Verde, Curaçao, Jordan and Uzbekistan debuted in 2026.

### UEFA sides England has never played
Question: Which UEFA teams has England never played against?
Teaches: Negate the match, not the opponent: “no match against England” rather than “a match against someone else”.
Reads as: Find teams where confederation is UEFA and name is not England, that never played matches, against England.
On the canvas:
```
FIND Team
  WHERE Confederation is UEFA
  AND Name is not "England"
  THAT never played Match
    THAT played against Team  [hidden]
      WHERE Name is "England"
```
```json
{
  "query": {
    "v": 1,
    "root": {
      "id": "t",
      "entity": "team",
      "relation": null,
      "join": "and",
      "items": [
        {
          "id": "c1",
          "kind": "cond",
          "property": "confederation",
          "op": "is",
          "value": "UEFA"
        },
        {
          "id": "c2",
          "kind": "cond",
          "property": "name",
          "op": "isNot",
          "value": "England"
        }
      ],
      "shown": true,
      "children": [
        {
          "id": "mt",
          "entity": "match",
          "relation": "played",
          "join": "and",
          "items": [],
          "shown": false,
          "children": [
            {
              "id": "o",
              "entity": "team",
              "relation": "playedAgainst",
              "join": "and",
              "items": [
                {
                  "id": "c3",
                  "kind": "cond",
                  "property": "name",
                  "op": "is",
                  "value": "England"
                }
              ],
              "shown": false,
              "children": []
            }
          ],
          "mode": "without"
        }
      ]
    },
    "grouping": null,
    "ranking": null
  }
}
```
Link: https://fq.rking.ie/?q=%7B%22q%22%3A%7B%22v%22%3A1%2C%22root%22%3A%7B%22id%22%3A%22t%22%2C%22entity%22%3A%22team%22%2C%22relation%22%3Anull%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c1%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22confederation%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22UEFA%22%7D%2C%7B%22id%22%3A%22c2%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22name%22%2C%22op%22%3A%22isNot%22%2C%22value%22%3A%22England%22%7D%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%7B%22id%22%3A%22mt%22%2C%22entity%22%3A%22match%22%2C%22relation%22%3A%22played%22%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%5D%2C%22shown%22%3Afalse%2C%22children%22%3A%5B%7B%22id%22%3A%22o%22%2C%22entity%22%3A%22team%22%2C%22relation%22%3A%22playedAgainst%22%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c3%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22name%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22England%22%7D%5D%2C%22shown%22%3Afalse%2C%22children%22%3A%5B%5D%7D%5D%2C%22mode%22%3A%22without%22%7D%5D%7D%2C%22grouping%22%3Anull%2C%22ranking%22%3Anull%7D%7D
Expected answer: Armenia, Faroe Islands and Gibraltar.

### Argentina's record against non-CONMEBOL sides met 10+ times
Question: Against which non-South American sides has Argentina played at least ten times, and how did it go?
Teaches: Group per a column, count rows and rows where a condition holds, then keep groups that pass a threshold.
Reads as: Find Argentina, that played matches, against a team where confederation is not CONMEBOL — per opponent: matches, wins, draws, losses, only where matches is at least 10.
On the canvas:
```
FIND Team  [hidden]
  WHERE Name is "Argentina"
  THAT played Match
    THAT played against Team  [hidden]
      WHERE Confederation is not CONMEBOL
⟶ PER Opponent
  COUNT Matches
  COUNT Wins
  COUNT Draws
  COUNT Losses
⟶ KEEP where Matches ≥ 10
```
```json
{
  "query": {
    "v": 1,
    "root": {
      "id": "a",
      "entity": "team",
      "relation": null,
      "join": "and",
      "items": [
        {
          "id": "c1",
          "kind": "cond",
          "property": "name",
          "op": "is",
          "value": "Argentina"
        }
      ],
      "shown": false,
      "children": [
        {
          "id": "mt",
          "entity": "match",
          "relation": "played",
          "join": "and",
          "items": [],
          "shown": true,
          "children": [
            {
              "id": "o",
              "entity": "team",
              "relation": "playedAgainst",
              "join": "and",
              "items": [
                {
                  "id": "c2",
                  "kind": "cond",
                  "property": "confederation",
                  "op": "isNot",
                  "value": "CONMEBOL"
                }
              ],
              "shown": false,
              "children": []
            }
          ]
        }
      ]
    },
    "grouping": {
      "by": [
        "mt.opponent"
      ],
      "measures": [
        {
          "id": "p",
          "fn": "count",
          "label": "Matches"
        },
        {
          "id": "w",
          "fn": "countWhere",
          "where": {
            "id": "x",
            "kind": "cond",
            "property": "result",
            "op": "is",
            "value": "Win"
          },
          "label": "Wins"
        },
        {
          "id": "d",
          "fn": "countWhere",
          "where": {
            "id": "y",
            "kind": "cond",
            "property": "result",
            "op": "is",
            "value": "Draw"
          },
          "label": "Draws"
        },
        {
          "id": "l",
          "fn": "countWhere",
          "where": {
            "id": "z",
            "kind": "cond",
            "property": "result",
            "op": "is",
            "value": "Loss"
          },
          "label": "Losses"
        }
      ],
      "having": [
        {
          "id": "h",
          "kind": "cond",
          "property": "m.p",
          "op": "gte",
          "value": 10
        }
      ]
    },
    "ranking": null
  }
}
```
Link: https://fq.rking.ie/?q=%7B%22q%22%3A%7B%22v%22%3A1%2C%22root%22%3A%7B%22id%22%3A%22a%22%2C%22entity%22%3A%22team%22%2C%22relation%22%3Anull%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c1%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22name%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22Argentina%22%7D%5D%2C%22shown%22%3Afalse%2C%22children%22%3A%5B%7B%22id%22%3A%22mt%22%2C%22entity%22%3A%22match%22%2C%22relation%22%3A%22played%22%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%7B%22id%22%3A%22o%22%2C%22entity%22%3A%22team%22%2C%22relation%22%3A%22playedAgainst%22%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c2%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22confederation%22%2C%22op%22%3A%22isNot%22%2C%22value%22%3A%22CONMEBOL%22%7D%5D%2C%22shown%22%3Afalse%2C%22children%22%3A%5B%5D%7D%5D%7D%5D%7D%2C%22grouping%22%3A%7B%22by%22%3A%5B%22mt.opponent%22%5D%2C%22measures%22%3A%5B%7B%22id%22%3A%22p%22%2C%22fn%22%3A%22count%22%2C%22label%22%3A%22Matches%22%7D%2C%7B%22id%22%3A%22w%22%2C%22fn%22%3A%22countWhere%22%2C%22where%22%3A%7B%22id%22%3A%22x%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22result%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22Win%22%7D%2C%22label%22%3A%22Wins%22%7D%2C%7B%22id%22%3A%22d%22%2C%22fn%22%3A%22countWhere%22%2C%22where%22%3A%7B%22id%22%3A%22y%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22result%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22Draw%22%7D%2C%22label%22%3A%22Draws%22%7D%2C%7B%22id%22%3A%22l%22%2C%22fn%22%3A%22countWhere%22%2C%22where%22%3A%7B%22id%22%3A%22z%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22result%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22Loss%22%7D%2C%22label%22%3A%22Losses%22%7D%5D%2C%22having%22%3A%5B%7B%22id%22%3A%22h%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22m.p%22%2C%22op%22%3A%22gte%22%2C%22value%22%3A10%7D%5D%7D%2C%22ranking%22%3Anull%7D%7D
Expected answer: 11 opponents, Mexico the most met.

### Brazil's longest winning runs
Question: What are Brazil's longest runs of consecutive wins?
Teaches: A streak block: what keeps the run going, across which matches, then rank by length.
Reads as: Find Brazil, with a streak of wins across all matches, keeping the top 5 by length.
On the canvas:
```
FIND Team
  WHERE Name is "Brazil"
  THAT has a Streak of Wins across all matches
⟶ KEEP top 5 by Length, highest first
```
```json
{
  "query": {
    "v": 1,
    "root": {
      "id": "t",
      "entity": "team",
      "relation": null,
      "join": "and",
      "items": [
        {
          "id": "c1",
          "kind": "cond",
          "property": "name",
          "op": "is",
          "value": "Brazil"
        }
      ],
      "shown": true,
      "children": [
        {
          "id": "s",
          "entity": "streak",
          "relation": "hasStreak",
          "join": "and",
          "items": [],
          "shown": true,
          "children": [],
          "streak": {
            "condition": "wins",
            "conditionItems": [],
            "scope": "all",
            "competitions": [],
            "scopeItems": [],
            "keep": null
          }
        }
      ]
    },
    "grouping": null,
    "ranking": {
      "column": "s.length",
      "dir": "desc",
      "n": 5
    }
  }
}
```
Link: https://fq.rking.ie/?q=%7B%22q%22%3A%7B%22v%22%3A1%2C%22root%22%3A%7B%22id%22%3A%22t%22%2C%22entity%22%3A%22team%22%2C%22relation%22%3Anull%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c1%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22name%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22Brazil%22%7D%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%7B%22id%22%3A%22s%22%2C%22entity%22%3A%22streak%22%2C%22relation%22%3A%22hasStreak%22%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%5D%2C%22streak%22%3A%7B%22condition%22%3A%22wins%22%2C%22conditionItems%22%3A%5B%5D%2C%22scope%22%3A%22all%22%2C%22competitions%22%3A%5B%5D%2C%22scopeItems%22%3A%5B%5D%2C%22keep%22%3Anull%7D%7D%5D%7D%2C%22grouping%22%3Anull%2C%22ranking%22%3A%7B%22column%22%3A%22s.length%22%2C%22dir%22%3A%22desc%22%2C%22n%22%3A5%7D%7D%7D
Expected answer: 14 wins in 1997 is the longest.

### Top scorer at every World Cup
Question: Who was the top scorer at each World Cup?
Teaches: Keep top N for each value of a column — here 1 per tournament, with ties kept.
Reads as: Find tournaments where competition is FIFA World Cup and competition type is Finals, that included matches, that had goals where it wasn't an own goal — per name and scorer and scored for: goals, keeping the top 1 by goals for each name, ties included.
On the canvas:
```
FIND Tournament
  WHERE Competition is "FIFA World Cup"
  AND Competition type is Finals
  THAT included Match  [hidden]
    THAT had Goal
      WHERE Own goal is no
⟶ PER Tournament · Name, Scorer, Scored for
  COUNT Goals
⟶ KEEP top 1 by Goals, highest first, ties kept, for each tournament · name
```
```json
{
  "query": {
    "v": 1,
    "root": {
      "id": "t",
      "entity": "tournament",
      "relation": null,
      "join": "and",
      "items": [
        {
          "id": "c1",
          "kind": "cond",
          "property": "competition",
          "op": "is",
          "value": "FIFA World Cup"
        },
        {
          "id": "c2",
          "kind": "cond",
          "property": "competitionType",
          "op": "is",
          "value": "Finals"
        }
      ],
      "shown": true,
      "children": [
        {
          "id": "mt",
          "entity": "match",
          "relation": "tournamentMatches",
          "join": "and",
          "items": [],
          "shown": false,
          "children": [
            {
              "id": "g",
              "entity": "goal",
              "relation": "had",
              "join": "and",
              "items": [
                {
                  "id": "c3",
                  "kind": "cond",
                  "property": "ownGoal",
                  "op": "is",
                  "value": false
                }
              ],
              "shown": true,
              "children": []
            }
          ]
        }
      ]
    },
    "grouping": {
      "by": [
        "t.name",
        "g.scorer",
        "g.team"
      ],
      "measures": [
        {
          "id": "n",
          "fn": "count",
          "label": "Goals"
        }
      ]
    },
    "ranking": {
      "column": "m.n",
      "dir": "desc",
      "n": 1,
      "per": [
        "t.name"
      ],
      "ties": true
    }
  }
}
```
Link: https://fq.rking.ie/?q=%7B%22q%22%3A%7B%22v%22%3A1%2C%22root%22%3A%7B%22id%22%3A%22t%22%2C%22entity%22%3A%22tournament%22%2C%22relation%22%3Anull%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c1%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22competition%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22FIFA%20World%20Cup%22%7D%2C%7B%22id%22%3A%22c2%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22competitionType%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22Finals%22%7D%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%7B%22id%22%3A%22mt%22%2C%22entity%22%3A%22match%22%2C%22relation%22%3A%22tournamentMatches%22%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%5D%2C%22shown%22%3Afalse%2C%22children%22%3A%5B%7B%22id%22%3A%22g%22%2C%22entity%22%3A%22goal%22%2C%22relation%22%3A%22had%22%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c3%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22ownGoal%22%2C%22op%22%3A%22is%22%2C%22value%22%3Afalse%7D%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%5D%7D%5D%7D%5D%7D%2C%22grouping%22%3A%7B%22by%22%3A%5B%22t.name%22%2C%22g.scorer%22%2C%22g.team%22%5D%2C%22measures%22%3A%5B%7B%22id%22%3A%22n%22%2C%22fn%22%3A%22count%22%2C%22label%22%3A%22Goals%22%7D%5D%7D%2C%22ranking%22%3A%7B%22column%22%3A%22m.n%22%2C%22dir%22%3A%22desc%22%2C%22n%22%3A1%2C%22per%22%3A%5B%22t.name%22%5D%2C%22ties%22%3Atrue%7D%7D%7D
Expected answer: Just Fontaine 13 in 1958, Kylian Mbappé 10 in 2026 and 8 in 2022; four joint leaders on 5 in 2010.

### World Cups won by a host
Question: Which World Cups were won by a host nation?
Teaches: An alias names a block so another can compare with it — here the winner against the host countries.
Reads as: Find tournaments where competition is FIFA World Cup and host countries includes ‹W›, won by ‹W›.
On the canvas:
```
FIND Tournament
  WHERE Competition is "FIFA World Cup"
  AND Host countries includes ‹W›
  THAT was won by Team  [as ‹W›, hidden]
```
```json
{
  "query": {
    "v": 1,
    "root": {
      "id": "t",
      "entity": "tournament",
      "relation": null,
      "join": "and",
      "items": [
        {
          "id": "c1",
          "kind": "cond",
          "property": "competition",
          "op": "is",
          "value": "FIFA World Cup"
        },
        {
          "id": "c2",
          "kind": "cond",
          "property": "hostCountries",
          "op": "includes",
          "value": {
            "alias": "W"
          }
        }
      ],
      "shown": true,
      "children": [
        {
          "id": "w",
          "entity": "team",
          "relation": "wonBy",
          "join": "and",
          "items": [],
          "shown": false,
          "children": [],
          "alias": "W"
        }
      ]
    },
    "grouping": null,
    "ranking": null
  }
}
```
Link: https://fq.rking.ie/?q=%7B%22q%22%3A%7B%22v%22%3A1%2C%22root%22%3A%7B%22id%22%3A%22t%22%2C%22entity%22%3A%22tournament%22%2C%22relation%22%3Anull%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c1%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22competition%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22FIFA%20World%20Cup%22%7D%2C%7B%22id%22%3A%22c2%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22hostCountries%22%2C%22op%22%3A%22includes%22%2C%22value%22%3A%7B%22alias%22%3A%22W%22%7D%7D%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%7B%22id%22%3A%22w%22%2C%22entity%22%3A%22team%22%2C%22relation%22%3A%22wonBy%22%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%5D%2C%22shown%22%3Afalse%2C%22children%22%3A%5B%5D%2C%22alias%22%3A%22W%22%7D%5D%7D%2C%22grouping%22%3Anull%2C%22ranking%22%3Anull%7D%7D
Expected answer: Six: Uruguay 1930, Italy 1934, England 1966, Germany 1974, Argentina 1978, France 1998.

### Holding the World Cup and the Euro at once
Question: Which countries held two major trophies at the same time — say the World Cup and the Euro?
Teaches: An alias's own properties as values: a title's reign runs from its End date to Title held until, and two reigns overlap when each starts before the other ends.
Reads as: Find tournaments — call it ‹First› — where competition is FIFA World Cup, won by a team, that won a tournament where competition is UEFA Euro, end date before ‹First›'s title held until and title held until after ‹First›'s end date.
On the canvas:
```
FIND Tournament  [as ‹First›]
  WHERE Competition is "FIFA World Cup"
  THAT was won by Team
    THAT won Tournament
      WHERE Competition is "UEFA Euro"
      AND End date before ‹First›'s Title held until
      AND Title held until after ‹First›'s End date
```
```json
{
  "query": {
    "v": 1,
    "root": {
      "id": "wc",
      "entity": "tournament",
      "relation": null,
      "join": "and",
      "items": [
        {
          "id": "c1",
          "kind": "cond",
          "property": "competition",
          "op": "is",
          "value": "FIFA World Cup"
        }
      ],
      "shown": true,
      "children": [
        {
          "id": "w",
          "entity": "team",
          "relation": "wonBy",
          "join": "and",
          "items": [],
          "shown": true,
          "children": [
            {
              "id": "eu",
              "entity": "tournament",
              "relation": "won",
              "join": "and",
              "items": [
                {
                  "id": "c2",
                  "kind": "cond",
                  "property": "competition",
                  "op": "is",
                  "value": "UEFA Euro"
                },
                {
                  "id": "c3",
                  "kind": "cond",
                  "property": "endDate",
                  "op": "before",
                  "value": {
                    "alias": "First",
                    "prop": "heldUntil"
                  }
                },
                {
                  "id": "c4",
                  "kind": "cond",
                  "property": "heldUntil",
                  "op": "after",
                  "value": {
                    "alias": "First",
                    "prop": "endDate"
                  }
                }
              ],
              "shown": true,
              "children": []
            }
          ]
        }
      ],
      "alias": "First"
    },
    "grouping": null,
    "ranking": null
  },
  "view": {
    "columns": [
      "w.name",
      "wc.name",
      "wc.heldUntil",
      "eu.name",
      "eu.heldUntil"
    ]
  }
}
```
Link: https://fq.rking.ie/?q=%7B%22q%22%3A%7B%22v%22%3A1%2C%22root%22%3A%7B%22id%22%3A%22wc%22%2C%22entity%22%3A%22tournament%22%2C%22relation%22%3Anull%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c1%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22competition%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22FIFA%20World%20Cup%22%7D%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%7B%22id%22%3A%22w%22%2C%22entity%22%3A%22team%22%2C%22relation%22%3A%22wonBy%22%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%7B%22id%22%3A%22eu%22%2C%22entity%22%3A%22tournament%22%2C%22relation%22%3A%22won%22%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c2%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22competition%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22UEFA%20Euro%22%7D%2C%7B%22id%22%3A%22c3%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22endDate%22%2C%22op%22%3A%22before%22%2C%22value%22%3A%7B%22alias%22%3A%22First%22%2C%22prop%22%3A%22heldUntil%22%7D%7D%2C%7B%22id%22%3A%22c4%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22heldUntil%22%2C%22op%22%3A%22after%22%2C%22value%22%3A%7B%22alias%22%3A%22First%22%2C%22prop%22%3A%22endDate%22%7D%7D%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%5D%7D%5D%7D%5D%2C%22alias%22%3A%22First%22%7D%2C%22grouping%22%3Anull%2C%22ranking%22%3Anull%7D%2C%22v%22%3A%7B%22columns%22%3A%5B%22w.name%22%2C%22wc.name%22%2C%22wc.heldUntil%22%2C%22eu.name%22%2C%22eu.heldUntil%22%5D%7D%7D
Expected answer: Five pairs: West Germany (Euro 1972 with World Cup 1974), France (1998 with 2000), Spain three times (World Cup 2010 with Euro 2008, then with Euro 2012; Euro 2024 with World Cup 2026, both still held). Swap in Copa América for Argentina and Brazil.

### UEFA sides' biggest wins, each match once
Question: What are the biggest wins in matches involving a UEFA side?
Teaches: A match reached through a team is one row per team that fits, so a UEFA v UEFA match comes twice. Each match once keeps one row per match.
Reads as: Find teams where confederation is UEFA, that played matches, keeping the top 10 by margin, each match once.
On the canvas:
```
FIND Team  [hidden]
  WHERE Confederation is UEFA
  THAT played Match
⟶ KEEP top 10 by Margin, highest first
(results: each match listed once)
```
```json
{
  "query": {
    "v": 1,
    "root": {
      "id": "t",
      "entity": "team",
      "relation": null,
      "join": "and",
      "items": [
        {
          "id": "c1",
          "kind": "cond",
          "property": "confederation",
          "op": "is",
          "value": "UEFA"
        }
      ],
      "shown": false,
      "children": [
        {
          "id": "mt",
          "entity": "match",
          "relation": "played",
          "join": "and",
          "items": [],
          "shown": true,
          "children": []
        }
      ]
    },
    "grouping": null,
    "ranking": {
      "column": "mt.margin",
      "dir": "desc",
      "n": 10
    },
    "once": true
  },
  "view": {
    "columns": [
      "mt.date",
      "mt.team",
      "mt.score",
      "mt.opponent",
      "mt.competition"
    ]
  }
}
```
Link: https://fq.rking.ie/?q=%7B%22q%22%3A%7B%22v%22%3A1%2C%22root%22%3A%7B%22id%22%3A%22t%22%2C%22entity%22%3A%22team%22%2C%22relation%22%3Anull%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c1%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22confederation%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22UEFA%22%7D%5D%2C%22shown%22%3Afalse%2C%22children%22%3A%5B%7B%22id%22%3A%22mt%22%2C%22entity%22%3A%22match%22%2C%22relation%22%3A%22played%22%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%5D%7D%5D%7D%2C%22grouping%22%3Anull%2C%22ranking%22%3A%7B%22column%22%3A%22mt.margin%22%2C%22dir%22%3A%22desc%22%2C%22n%22%3A10%7D%2C%22once%22%3Atrue%7D%2C%22v%22%3A%7B%22columns%22%3A%5B%22mt.date%22%2C%22mt.team%22%2C%22mt.score%22%2C%22mt.opponent%22%2C%22mt.competition%22%5D%7D%7D
Expected answer: Kazakhstan 20–1 Guam (1997), Germany 16–0 Russia (1912), Denmark 17–1 France (1908), France 14–0 Gibraltar (2023)… each once. Starting from Match, + played by → Team (UEFA) gives the same list with no team in focus.

### Defending champions out in the group stage
Question: Which World Cup holders went out in the group stage of the next one?
Teaches: Previous/next edition carries the team in focus, so Finish is the champions' own finish at the next tournament.
Reads as: Find teams, that won a tournament where competition is FIFA World Cup, whose next edition was a tournament where finish is Group stage.
On the canvas:
```
FIND Team
  THAT won Tournament  [hidden]
    WHERE Competition is "FIFA World Cup"
    THAT next edition Tournament
      WHERE Finish is Group stage
```
```json
{
  "query": {
    "v": 1,
    "root": {
      "id": "t",
      "entity": "team",
      "relation": null,
      "join": "and",
      "items": [],
      "shown": true,
      "children": [
        {
          "id": "w",
          "entity": "tournament",
          "relation": "won",
          "join": "and",
          "items": [
            {
              "id": "c1",
              "kind": "cond",
              "property": "competition",
              "op": "is",
              "value": "FIFA World Cup"
            }
          ],
          "shown": false,
          "children": [
            {
              "id": "n",
              "entity": "tournament",
              "relation": "nextEdition",
              "join": "and",
              "items": [
                {
                  "id": "c2",
                  "kind": "cond",
                  "property": "finish",
                  "op": "is",
                  "value": "Group stage"
                }
              ],
              "shown": true,
              "children": []
            }
          ]
        }
      ]
    },
    "grouping": null,
    "ranking": null
  }
}
```
Link: https://fq.rking.ie/?q=%7B%22q%22%3A%7B%22v%22%3A1%2C%22root%22%3A%7B%22id%22%3A%22t%22%2C%22entity%22%3A%22team%22%2C%22relation%22%3Anull%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%7B%22id%22%3A%22w%22%2C%22entity%22%3A%22tournament%22%2C%22relation%22%3A%22won%22%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c1%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22competition%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22FIFA%20World%20Cup%22%7D%5D%2C%22shown%22%3Afalse%2C%22children%22%3A%5B%7B%22id%22%3A%22n%22%2C%22entity%22%3A%22tournament%22%2C%22relation%22%3A%22nextEdition%22%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c2%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22finish%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22Group%20stage%22%7D%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%5D%7D%5D%7D%5D%7D%2C%22grouping%22%3Anull%2C%22ranking%22%3Anull%7D%7D
Expected answer: Italy 1950, Brazil 1966, France 2002, Italy 2010, Spain 2014, Germany 2018.

### Longest waits between a player's goals
Question: Which player went longest between two international goals?
Teaches: Worked-out properties (here Years since their previous goal) rank like any other column.
Reads as: Find goals where it wasn't an own goal, keeping the top 10 by years since their previous goal.
On the canvas:
```
FIND Goal
  WHERE Own goal is no
⟶ KEEP top 10 by Years since their previous goal, highest first
```
```json
{
  "query": {
    "v": 1,
    "root": {
      "id": "g",
      "entity": "goal",
      "relation": null,
      "join": "and",
      "items": [
        {
          "id": "c1",
          "kind": "cond",
          "property": "ownGoal",
          "op": "is",
          "value": false
        }
      ],
      "shown": true,
      "children": []
    },
    "grouping": null,
    "ranking": {
      "column": "g.sincePrevious",
      "dir": "desc",
      "n": 10
    }
  },
  "view": {
    "columns": [
      "g.scorer",
      "g.team",
      "g.date",
      "g.match",
      "g.sincePrevious"
    ]
  }
}
```
Link: https://fq.rking.ie/?q=%7B%22q%22%3A%7B%22v%22%3A1%2C%22root%22%3A%7B%22id%22%3A%22g%22%2C%22entity%22%3A%22goal%22%2C%22relation%22%3Anull%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c1%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22ownGoal%22%2C%22op%22%3A%22is%22%2C%22value%22%3Afalse%7D%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%5D%7D%2C%22grouping%22%3Anull%2C%22ranking%22%3A%7B%22column%22%3A%22g.sincePrevious%22%2C%22dir%22%3A%22desc%22%2C%22n%22%3A10%7D%7D%2C%22v%22%3A%7B%22columns%22%3A%5B%22g.scorer%22%2C%22g.team%22%2C%22g.date%22%2C%22g.match%22%2C%22g.sincePrevious%22%5D%7D%7D
Expected answer: The top five (Aubameyang, Manuel Fernandes, Serginho, Teboho Mokoena, Joaquín) are namesakes or a source error just under the 20-year split; Mágico González's 14.7 years (1977–92) is the longest clearly genuine wait.

### Most minutes played at World Cups
Question: Who has spent longest on the pitch at World Cup finals?
Teaches: Appearance is one player in one match — group appearances by player and sum their minutes.
Reads as: Find appearances where competition is FIFA World Cup — per player and team: total minutes, matches, keeping the top 10 by minutes.
On the canvas:
```
FIND Appearance
  WHERE Competition is "FIFA World Cup"
⟶ PER Player, Team
  TOTAL Minutes
  COUNT Appearances  as “Matches”
⟶ KEEP top 10 by Minutes, highest first
```
```json
{
  "query": {
    "v": 1,
    "root": {
      "id": "a",
      "entity": "appearance",
      "relation": null,
      "join": "and",
      "items": [
        {
          "id": "c1",
          "kind": "cond",
          "property": "competition",
          "op": "is",
          "value": "FIFA World Cup"
        }
      ],
      "shown": true,
      "children": []
    },
    "grouping": {
      "by": [
        "a.player",
        "a.team"
      ],
      "measures": [
        {
          "id": "mins",
          "fn": "sum",
          "column": "a.minutes",
          "label": "Minutes"
        },
        {
          "id": "n",
          "fn": "count",
          "label": "Matches"
        }
      ]
    },
    "ranking": {
      "column": "m.mins",
      "dir": "desc",
      "n": 10
    }
  }
}
```
Link: https://fq.rking.ie/?q=%7B%22q%22%3A%7B%22v%22%3A1%2C%22root%22%3A%7B%22id%22%3A%22a%22%2C%22entity%22%3A%22appearance%22%2C%22relation%22%3Anull%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c1%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22competition%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22FIFA%20World%20Cup%22%7D%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%5D%7D%2C%22grouping%22%3A%7B%22by%22%3A%5B%22a.player%22%2C%22a.team%22%5D%2C%22measures%22%3A%5B%7B%22id%22%3A%22mins%22%2C%22fn%22%3A%22sum%22%2C%22column%22%3A%22a.minutes%22%2C%22label%22%3A%22Minutes%22%7D%2C%7B%22id%22%3A%22n%22%2C%22fn%22%3A%22count%22%2C%22label%22%3A%22Matches%22%7D%5D%7D%2C%22ranking%22%3A%7B%22column%22%3A%22m.mins%22%2C%22dir%22%3A%22desc%22%2C%22n%22%3A10%7D%7D%7D
Expected answer: Lionel Messi, 3,054 minutes in 34 matches; then Paolo Maldini (2,220) and Cristiano Ronaldo (2,205). Line-ups are known for World Cups since 1970.

### Spain's most-used partnerships
Question: Which two Spain players have played together most often?
Teaches: Played alongside links a player to team-mates, with the first in focus: Matches shared counts their games together, and grouping by Pair counts each pair once.
Reads as: Find players where played for is Spain, that played alongside a player — per pair: highest matches shared, keeping the top 10 by matches together.
On the canvas:
```
FIND Player  [hidden]
  WHERE Played for is "Spain"
  THAT played alongside Player
⟶ PER Pair
  HIGHEST Matches shared  as “Matches together”
⟶ KEEP top 10 by Matches together, highest first
```
```json
{
  "query": {
    "v": 1,
    "root": {
      "id": "p",
      "entity": "player",
      "relation": null,
      "join": "and",
      "items": [
        {
          "id": "c1",
          "kind": "cond",
          "property": "team",
          "op": "is",
          "value": "Spain"
        }
      ],
      "shown": false,
      "children": [
        {
          "id": "mate",
          "entity": "player",
          "relation": "playedAlongside",
          "join": "and",
          "items": [],
          "shown": true,
          "children": []
        }
      ]
    },
    "grouping": {
      "by": [
        "mate.pair"
      ],
      "measures": [
        {
          "id": "together",
          "fn": "max",
          "column": "mate.sharedMatches",
          "label": "Matches together"
        }
      ]
    },
    "ranking": {
      "column": "m.together",
      "dir": "desc",
      "n": 10
    }
  }
}
```
Link: https://fq.rking.ie/?q=%7B%22q%22%3A%7B%22v%22%3A1%2C%22root%22%3A%7B%22id%22%3A%22p%22%2C%22entity%22%3A%22player%22%2C%22relation%22%3Anull%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c1%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22team%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22Spain%22%7D%5D%2C%22shown%22%3Afalse%2C%22children%22%3A%5B%7B%22id%22%3A%22mate%22%2C%22entity%22%3A%22player%22%2C%22relation%22%3A%22playedAlongside%22%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%5D%7D%5D%7D%2C%22grouping%22%3A%7B%22by%22%3A%5B%22mate.pair%22%5D%2C%22measures%22%3A%5B%7B%22id%22%3A%22together%22%2C%22fn%22%3A%22max%22%2C%22column%22%3A%22mate.sharedMatches%22%2C%22label%22%3A%22Matches%20together%22%7D%5D%7D%2C%22ranking%22%3A%7B%22column%22%3A%22m.together%22%2C%22dir%22%3A%22desc%22%2C%22n%22%3A10%7D%7D%7D
Expected answer: Andrés Iniesta & Sergio Ramos, 112 matches together; Iker Casillas & Xavi, 106; Casillas & Ramos, 103 — in recorded line-ups, so from 2001 on.

### Messi's longest runs of competitive starts
Question: How many competitive matches in a row has Messi started?
Teaches: A player's runs work like a team's streaks: consecutive appearances, starts, whole matches or scoring appearances. Matches whose line-ups aren't known are skipped.
Reads as: Find Lionel Messi, with a run of consecutive starts across competitive matches, keeping the top 3 by length.
On the canvas:
```
FIND Player  [hidden]
  WHERE Name is "Lionel Messi"
  THAT has a Run of Starts across competitive matches
⟶ KEEP top 3 by Length, highest first
```
```json
{
  "query": {
    "v": 1,
    "root": {
      "id": "p",
      "entity": "player",
      "relation": null,
      "join": "and",
      "items": [
        {
          "id": "c1",
          "kind": "cond",
          "property": "name",
          "op": "is",
          "value": "Lionel Messi"
        }
      ],
      "shown": false,
      "children": [
        {
          "id": "s",
          "entity": "streak",
          "relation": "playerRun",
          "join": "and",
          "items": [],
          "shown": true,
          "children": [],
          "streak": {
            "condition": "started",
            "conditionItems": [],
            "scope": "competitive",
            "competitions": [],
            "scopeItems": [],
            "keep": null
          }
        }
      ]
    },
    "grouping": null,
    "ranking": {
      "column": "s.length",
      "dir": "desc",
      "n": 3
    }
  }
}
```
Link: https://fq.rking.ie/?q=%7B%22q%22%3A%7B%22v%22%3A1%2C%22root%22%3A%7B%22id%22%3A%22p%22%2C%22entity%22%3A%22player%22%2C%22relation%22%3Anull%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%7B%22id%22%3A%22c1%22%2C%22kind%22%3A%22cond%22%2C%22property%22%3A%22name%22%2C%22op%22%3A%22is%22%2C%22value%22%3A%22Lionel%20Messi%22%7D%5D%2C%22shown%22%3Afalse%2C%22children%22%3A%5B%7B%22id%22%3A%22s%22%2C%22entity%22%3A%22streak%22%2C%22relation%22%3A%22playerRun%22%2C%22join%22%3A%22and%22%2C%22items%22%3A%5B%5D%2C%22shown%22%3Atrue%2C%22children%22%3A%5B%5D%2C%22streak%22%3A%7B%22condition%22%3A%22started%22%2C%22conditionItems%22%3A%5B%5D%2C%22scope%22%3A%22competitive%22%2C%22competitions%22%3A%5B%5D%2C%22scopeItems%22%3A%5B%5D%2C%22keep%22%3Anull%7D%7D%5D%7D%2C%22grouping%22%3Anull%2C%22ranking%22%3A%7B%22column%22%3A%22s.length%22%2C%22dir%22%3A%22desc%22%2C%22n%22%3A3%7D%7D%7D
Expected answer: 42 competitive starts in a row from July 2007 to June 2013, ended against Ecuador; then 32 (August 2017 – October 2021).

## Data caveats

- Scores are after extra time. `result` counts a shootout as a draw; `resultPens` counts it for the winner.
- Sources: results and scorers from openfootball/internationals; later results, missing scorers and shootout winners from martj42/international_results; World Cup line-ups, substitutions, bookings and scorers (1970–2022) from the Fjelstul World Cup Database; line-ups, cards and scorers from ESPN (most competitive matches since about 2003, friendlies since about 2016). `scorersFrom`, `lineupsFrom` and `cardsFrom` on a match say which, or "none".
- Scorers are named for about 46% of all goals: every World Cup goal and about 80% of friendly goals since 2016, few in friendlies before then. Goal counts, player totals, hat-tricks and goal-based streaks are lower bounds.
- Line-ups and cards: where `lineupsKnown` / `cardsKnown` are false nothing is recorded, so caps, starts and card counts are lower bounds too. For averages per match, keep only complete matches — `scorersKnown`, `lineupsKnown` and `cardsKnown` all true (the builder's *Full record only* shortcut). ESPN's feed repeats some events word for word; the merge drops exact repeats. Coverage since 1970: competitive matches 5% before 2003 (World Cups only), about 55% 2003–2015 and 85% since 2016; friendlies about 25% 2003–2015 and 81% since 2016.
- The run of play (goal role, comeback, lead changes, scoredFirst, trailed) exists only where every goal in a match has a scorer; otherwise those values are null ("unknown").
- A player is a name + the side they played for. The same name on record for the same side with more than 20 years between one match and the next is split into two players (`namesakeSplit`). Players come from line-ups, goals and cards, so before line-ups were recorded a player exists only if they scored or were booked. Names are matched ignoring accents, case, word order and letters like ø/ð, and the sources' player ids join two spellings of one person; two ids under one name are two people only when both played in the same match (ESPN often gives one player several ids).
- Appearances: one per player per match in a known line-up. `minutes` runs from coming on (0 for a starter) to the final whistle (90, or 120 after extra time), being taken off or being sent off; stoppage time counts as the 45th or 90th minute. `debut` is true only where the side's line-ups go back two years unbroken, otherwise unknown for a first recorded cap. `position` comes from the sources; ESPN gives none for substitutes, so a player's position is the commonest they have.
- Played alongside / against (player → player) put the first player in focus: the second gains `sharedMatches`, `sharedStarts`, `sharedWins` and `pair` (both names in order — group by it so each pair counts once).
- Finish needs named stages (most major finals have them; many regional cups don't). Tournaments decided by a final group (1950 World Cup, pre-1975 Copa América) have no winner.
- Elo is World Football Elo computed here from every result since 1872 (start 1500; K by match weight; goal-margin multiplier; +100 home advantage).
- Qualifying "tournaments" are split by calendar year. Confederation is inferred from continental competitions entered.
