Skip to content
Mixed

Is the split unfair?

After 33 games the Scottish Premiership splits in two, and every spring someone calls it unfair. Over 25 seasons, the home games even out, but the fixtures don't. The side 7th at the split takes 2.6 more points from the last five than the side 6th.

Beginner

Contents

The claim

"The split is unfair." After 33 games, the Scottish Premiership divides into a top six and a bottom six, and each plays the other five in its half once more. Every spring the complaints come in: some teams get three home games out of five and others only two, and the final table ends up with a side in the bottom half on more points than one above it.

Why people believe it

Because you can see it in the table. A side can finish seventh with more points than sixth, and that looks wrong on the face of it. The home-game grumble is easy to believe too: three home games against two sounds like a head start when there are only five to play.

The data

Every Scottish Premiership match from 2000/01, when the split began, to 2025/26: 25 seasons with a split. 2019/20 is left out: it was stopped by COVID before the split was played. Final scores only, from football-data.co.uk.

The method

Before the split, every pair of teams meets three times. After it, sides in the same half meet a fourth time. So each pair's fourth meeting identifies a post-split match, and which teams play each other after the split identifies the two halves. Then:

  • Home games: for each post-split match, check whether it's played at the ground of the team that had hosted only one of the pair's three earlier meetings, and count each team's home games over the whole season.
  • Fixtures: compare the sides sitting 6th and 7th at the split, before and after it.
  • The table: count the seasons in which a bottom-six side finished with more points than a top-six side.

The evidence

The home games even out

Three home games out of five sounds like an advantage, but look at the whole season:

  • In 638 of 750 post-split matches (85%), the home side was the team that had hosted only one of the pair's three earlier meetings. The fourth meeting makes it two home games each.
  • Over the season, 274 of 300 team-seasons had exactly 19 home games and 19 away. The rest had 18 or 20.

A side with three home games after the split usually had fewer at home before it. And even where it doesn't balance, an extra home game after the split is worth about 0.23 points: home sides took 1.50 points a game, away sides 1.27. A small edge, in line with home advantage being worth about a quarter of a goal a game.

The fixtures don't

After the split, sixth plays the five best sides in the league, including Celtic and Rangers. Seventh plays the five worst. Here's what that does, averaged over 25 seasons:

The side 6th at the split has been the better team, but over the last five games it takes 0.85 points a game against the league's best. The side in 7th, playing the weakest, takes 1.36.
At the split Points a game, first 33 Points from the last 5
6th 1.32 4.24
7th 1.22 6.80

The side in 7th has been the weaker team all season, yet it takes 2.6 more points from the last five games, purely because of who it plays.

So the table ends up out of order

In 17 of 25 seasons, a bottom-six side finished with more points than at least one top-six side. The biggest gaps:

Season Bottom six Top six
2021/22 Livingston, 49 Ross County, 41
2014/15 Hamilton, 53 Dundee, 45
2010/11 Inverness CT, 53 Motherwell, 46
2002/03 Hibernian, 51 Dundee, 44
2023/24 Aberdeen, 48 Dundee, 42

That's not a scheduling accident; it's what the split is designed to do. The halves are fixed at 33 games, so a side can't climb into the top six after it, however many points it takes.

Verdict

Mixed. The home-game complaint doesn't hold up: the post-split fixtures mostly even out who has played at home, nine in ten sides end the season with exactly 19 home games, and an extra one is worth about a quarter of a point. But the table complaint does. After the split, the sides around sixth and seventh play completely different opposition, the side in 7th typically takes 2.6 more points than the side in 6th, and in 17 of 25 seasons the final table has a bottom-six side on more points than a top-six one. Whether that's unfair is a matter of taste; that it happens is a matter of fact.

Caveats

  • Points only. Points deductions aren't in the results files, so a few final totals differ from the official table.
  • The split is decided on 33 games, not 38. A side that's 7th at the split can finish above 6th on points and still be listed below; that's the rule, not an error in the data.
  • Averages hide variety. Some sixth-placed sides do well after the split, and some seventh-placed ones collapse; these are 25-season averages.
  • Home advantage varies. 0.23 points is the average over these seasons; it was smaller in 2020/21, behind closed doors.

Reproduce the analysis

The results files are published by football-data.co.uk. Download the Premiership file (SC0) for each season from 2000/01 to 2025/26 and save each under its own name, such as SC0_2425.csv; they aren't rehosted on this site. Then:

import csv
from collections import Counter, defaultdict
from datetime import datetime

POINTS = {"H": (3, 0), "D": (1, 1), "A": (0, 3)}
names = [f"{y % 100:02d}{(y + 1) % 100:02d}" for y in range(2000, 2026) if y != 2019]  # 2019/20 had no split
evens, homes, split_home, split_away = Counter(), Counter(), [], []
at_split = defaultdict(lambda: [0, 0])  # 6th and 7th at the split: points before, points after
overtaken = []
for s in names:
    with open(f"SC0_{s}.csv", encoding="latin-1") as f:
        games = [r for r in csv.DictReader(f) if r.get("FTR") in POINTS]
    games.sort(key=lambda r: datetime.strptime(r["Date"], "%d/%m/%Y" if len(r["Date"]) == 10 else "%d/%m/%y"))
    meetings = defaultdict(list)
    for r in games:
        meetings[frozenset((r["HomeTeam"], r["AwayTeam"]))].append(r)
    # every pair meets three times before the split; sides in the same half meet a fourth time after it
    half, after = defaultdict(set), set()
    for pair, m in meetings.items():
        if len(m) == 4:
            a, b = pair
            half[a].add(b); half[b].add(a); after.add(id(m[3]))
            hosted_before = sum(r["HomeTeam"] == m[3]["HomeTeam"] for r in m[:3])
            evens["evens the pair up" if hosted_before == 1 else "doesn't"] += 1
    before, after_pts, gd, total = Counter(), Counter(), Counter(), Counter()
    for r in games:
        h, a = r["HomeTeam"], r["AwayTeam"]
        hp, ap = POINTS[r["FTR"]]
        homes[h, s] += 1
        total[h] += hp; total[a] += ap
        if id(r) in after:
            after_pts[h] += hp; after_pts[a] += ap
            split_home.append(hp); split_away.append(ap)
        else:
            before[h] += hp; before[a] += ap
            gd[h] += int(r["FTHG"]) - int(r["FTAG"]); gd[a] += int(r["FTAG"]) - int(r["FTHG"])
    teams = set(total)
    leader = max(teams, key=before.get)
    top6 = {leader} | half[leader]
    sixth = min(top6, key=lambda t: (before[t], gd[t]))
    seventh = max(teams - top6, key=lambda t: (before[t], gd[t]))
    for place, t in (("6th", sixth), ("7th", seventh)):
        at_split[place][0] += before[t]; at_split[place][1] += after_pts[t]
    lowest_top, best_bottom = min(top6, key=total.get), max(teams - top6, key=total.get)
    if total[best_bottom] > total[lowest_top]:
        overtaken.append((total[best_bottom] - total[lowest_top], s, best_bottom, total[best_bottom], lowest_top, total[lowest_top]))

print("post-split fixture:", dict(evens))
print("home games in a season:", dict(Counter(homes.values())))
print(f"after the split: home side {sum(split_home) / len(split_home):.2f} points a game, away side {sum(split_away) / len(split_away):.2f}")
for place, (pre, post) in at_split.items():
    print(f"{place} at the split: {pre / len(names) / 33:.2f} a game before, {post / len(names):.2f} points from the last five")
print(f"a bottom-six side finished above a top-six side on points in {len(overtaken)} of {len(names)} seasons")
for gap, s, b, bp, t, tp in sorted(overtaken, reverse=True)[:5]:
    print(f"  20{s[:2]}/{s[2:]}: {b} {bp} points in the bottom six, {t} {tp} in the top six")

Spotted a flaw in the method, or have a football claim you'd like tested? Suggest it on LinkedIn, where discussion of these articles happens.

Get new pieces by email

An email when something new is published, and the occasional update. Unsubscribe in one click. How your email is used.