Baselight
with fifa_club_world_cup_matches as (
select home_teams.name as home_team, away_teams.name as away_team, matches.*, odds.*
from @blt.ultimate_soccer_dataset.matches matches
inner join @blt.ultimate_soccer_dataset.teams home_teams ON (matches.home_team_id = home_teams.team_id)
inner join @blt.ultimate_soccer_dataset.teams away_teams ON (matches.away_team_id = away_teams.team_id)
inner join @blt.ultimate_soccer_dataset.seasons s ON (matches.season_id = s.season_id)
inner join @blt.ultimate_soccer_dataset.competitions c ON (s.competition_id = c.competition_id)
inner join @blt.ultimate_soccer_dataset.match_betting_odds odds ON (odds.match_id = matches.match_id)
where 1=1
      and c.name = 'FIFA Club World Cup'
      and year(s.start_date) = 2025      
      and market = 'Match Winner'
      and matches.status = 'Match Finished'
),
pre_match AS (  -- 1. keep only pre-match “Match Winner” odds
    SELECT
        match_id,
        outcome,                           -- 'Home', 'Draw', 'Away'
        AVG(odds) AS avg_odds              -- average across bookmakers
    FROM fifa_club_world_cup_matches
    WHERE market     = 'Match Winner'
      AND odds_type  = 'pre_match'
    GROUP BY match_id, outcome
),
pivot1 AS (         -- 2. put the three outcomes on one row per match
    SELECT
        match_id,
        MIN(CASE WHEN outcome = 'Home' THEN avg_odds END) AS home_odds,
        MIN(CASE WHEN outcome = 'Draw' THEN avg_odds END) AS draw_odds,
        MIN(CASE WHEN outcome = 'Away' THEN avg_odds END) AS away_odds
    FROM pre_match
    GROUP BY match_id
),
prob AS (          -- 3. convert odds → implied probabilities (raw)
    SELECT
        p.match_id,
        1 / p.home_odds  AS raw_home_prob,
        1 / p.draw_odds  AS raw_draw_prob,
        1 / p.away_odds  AS raw_away_prob,
        m.home_team,
        m.away_team,
        m.date,
        m.home_score,
        m.away_score
    FROM pivot1 p
    JOIN fifa_club_world_cup_matches m USING (match_id)
    GROUP BY
        p.match_id, p.home_odds, p.draw_odds, p.away_odds,
        m.home_team, m.away_team, m.date, m.home_score, m.away_score
),
normalised AS (    -- 4. normalise so the three probs sum to 1
    SELECT
        *,
        raw_home_prob + raw_draw_prob + raw_away_prob AS total_p
    FROM prob
),
final AS (         -- 5. map actual result → its pre-match probability
    SELECT
        *,
        raw_home_prob / total_p AS home_prob,
        raw_draw_prob / total_p AS draw_prob,
        raw_away_prob / total_p AS away_prob,
        CASE
            WHEN home_score > away_score THEN 'home'
            WHEN home_score < away_score THEN 'away'
            ELSE 'draw'
        END AS actual_outcome
    FROM normalised
)
SELECT
    home_team || ' - ' || away_team as teams,
    --home_team,
    --away_team,
    strftime(date, '%Y-%m-%d') as match_date,
    home_score,
    away_score,
    --round(home_prob,2) as home_probability,
    --round(draw_prob,2) as draw_probability,
    --round(away_prob,2) as away_probability,
    CASE
            WHEN home_prob >= draw_prob AND home_prob >= away_prob THEN 'home'
            WHEN away_prob >= draw_prob AND away_prob >  home_prob THEN 'away'
            ELSE 'draw'                                        -- ties favour draw
    END AS favourite,
    round(greatest(home_prob, draw_prob, away_prob), 2) as favourite_probability, 
    actual_outcome,
    round(CASE
        WHEN actual_outcome = 'home' THEN home_prob
        WHEN actual_outcome = 'away' THEN away_prob
        ELSE draw_prob
    END, 2) AS actual_probability,                -- probability bookmakers gave to what happened
    CASE WHEN favourite_probability = actual_probability THEN 'Yes' ELSE 'No' END as correct_odds,
FROM final
ORDER BY actual_probability ASC                
teamsmatch_datehome_scoreaway_scorefavouritefavourite_probabilityactual_outcomeactual_probabilitycorrect_odds
Real Madrid - Al-Hilal Saudi FC2025-06-1811home0.73draw0.16No
Inter Miami - FC Porto2025-06-1921away0.56home0.2No
Fluminense - Borussia Dortmund2025-06-1700away0.6draw0.22No
Monterrey - Inter2025-06-1811away0.62draw0.22No
Boca Juniors - Benfica2025-06-1622away0.56draw0.25No
Al Ahly - Inter Miami2025-06-1500away0.45draw0.26No
Palmeiras - FC Porto2025-06-1500home0.38draw0.3No
Ulsan Hyundai FC - Mamelodi Sundowns2025-06-1701away0.37away0.37Yes
Pachuca - Red Bull Salzburg2025-06-1812away0.39away0.39Yes
Botafogo - Seattle Sounders2025-06-1621home0.47home0.47Yes
Paris Saint Germain - Atletico Madrid2025-06-1540home0.49home0.49Yes
Palmeiras - Al Ahly2025-06-1920home0.59home0.59Yes
River Plate - Urawa2025-06-1731home0.61home0.61Yes
Seattle Sounders - Atletico Madrid2025-06-1913away0.71away0.71Yes
Flamengo - ES Tunis2025-06-1720home0.72home0.72Yes
Chelsea - Los Angeles FC2025-06-1620home0.73home0.73Yes
Al Ain - Juventus2025-06-1905away0.76away0.76Yes
Manchester City - Wydad AC2025-06-1820home0.89home0.89Yes
Bayern München - Auckland City2025-06-15100home0.95home0.95Yes

Share link

Anyone who has the link will be able to view this.