# Bottom at Christmas, down in May?

Source: https://www.bryanmcguire.co.uk/myth-or-maths/bottom-at-christmas
Published: 2026-09-30

> One of football's oldest sayings is that the side bottom at Christmas goes down. In the Scottish Premiership it's mostly true. Of 26 sides bottom on Christmas Day, 18 finished bottom, and every one that escaped was within a point of the side above.

## The claim

"Bottom at Christmas, down in May." It's one of football's oldest sayings: whoever is propping up the table when the decorations go up is the side that'll finish there. Every December someone quotes it, and every December the side at the bottom insists there's plenty of football left.

## Why people believe it

By Christmas, a Scottish Premiership side has played about half its matches. That's enough for the table to mean something, and a side at the bottom has usually got there by being the weakest in the league, not by bad luck alone. Fans also remember the escapes precisely because they're unusual, which makes the rule feel even stronger.

## The data

Every Scottish Premiership season from 2000/01 to 2025/26: 26 seasons, 12 teams each, from the [football-data.co.uk](https://www.football-data.co.uk/scotlandm.php) results files.

## The method

For each season, build the table from every match played before 25 December, ranking on points, then goal difference, then goals scored. Take the side at the bottom, note how many points behind the side above it was, and compare with where it finished the season. The test is **finishing bottom**, not being relegated, because the relegation rules have changed over the years (see Caveats).

## The evidence

### How often the saying comes true

| Where the side bottom at Christmas finished | Seasons |
|---|---|
| Bottom | **18** |
| Second-bottom | 3 |
| Higher | 5 |

**18 of 26**, a little over two-thirds, finished where they were at Christmas, and 21 of 26 finished in the bottom two. Being close to the bottom is dangerous too: the side **second**-bottom at Christmas went on to finish bottom 6 times.

### The gap matters more than the place

The saying treats bottom as bottom. The table doesn't: a side level on points with the one above is in a very different position from one seven points adrift.

<figure class="rank-chart">
<div role="img" aria-label="Each season's bottom side on Christmas Day, placed by how many points behind the side above it was, from 0 to 9. All five escapes came from sides level on points or one point behind. Every side two or more points behind finished in the bottom two, eleven of the fourteen at the very bottom.">

</div>
<figcaption>One dot per season. Sides level with, or a point behind, the team above at Christmas escaped five times out of twelve. Sides two or more points behind never got out of the bottom two.</figcaption>
</figure>

| Behind at Christmas | Seasons | Bottom | Bottom two |
|---|---|---|---|
| 0 or 1 point | 12 | 7 | 7 |
| 2 or more | 14 | 11 | **14** |

A side level with, or a point behind, the team above finished bottom 7 times in 12. Two points or more, and every one of the 14 finished in the bottom two. Even two points is a lot to make up on one specific side, when that side is picking up points too.

### The five escapes

| Side | At Christmas | Finished |
|---|---|---|
| Livingston 2004/05 | 15 from 18, level | 10th |
| Hamilton 2008/09 | 17 from 19, level | 9th |
| Aberdeen 2010/11 | 10 from 16, level | 9th |
| Ross County 2013/14 | 11 from 16, 1 behind | **7th** |
| Ross County 2020/21 | 13 from 19, 1 behind | 10th |

"15 from 18" is points from games played; "level" means level on points with the side above, bottom on goal difference.

Every escape came from a side that was only bottom by a point, or on goal difference. Ross County's 2013/14 is the biggest: bottom at Christmas, seventh in May, top of the bottom six.

## Verdict

**Supported.** The side bottom on Christmas Day finished bottom 18 times in 26, and in the bottom two 21 times. The saying is too blunt in one way: it's the size of the gap, not the position, that decides it. Level on points or a point behind, the escape rate is nearly half. Two points or more behind, not one side in 26 seasons got out of the bottom two.

## Caveats

- **Bottom isn't always relegated.** In 2002/03 Motherwell finished bottom but stayed up, because the First Division champions' ground didn't meet the league's criteria. Since 2014/15 the second-bottom side has also faced a play-off. This analysis only asks who finished bottom.
- **Points only.** Points deductions aren't in the results files, so a few tables differ slightly from the official ones.
- **2019/20 ended early.** The season stopped in March and was decided on points per game; the data holds the matches played. Hearts were bottom either way.
- **Games in hand.** By Christmas, sides had played between 16 and 21 matches, so a small gap can hide a game in hand either way.
- **One league.** A 12-team league with a split in spring may behave differently from a 20-team one.

## Reproduce the analysis

The results files are published by [football-data.co.uk](https://www.football-data.co.uk/scotlandm.php). 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:

```python
import csv
from collections import Counter
from datetime import datetime

names = [f"{y % 100:02d}{(y + 1) % 100:02d}" for y in range(2000, 2026)]

def season(s):
    with open(f"SC0_{s}.csv", encoding="latin-1") as f:
        games = [r for r in csv.DictReader(f) if r.get("FTR") in ("H", "D", "A")]
    for r in games:
        r["date"] = datetime.strptime(r["Date"], "%d/%m/%Y" if len(r["Date"]) == 10 else "%d/%m/%y")
    return games

def table(games):
    """Teams in league order: points, then goal difference, then goals scored."""
    pts, gd, gf, played = Counter(), Counter(), Counter(), Counter()
    for r in games:
        h, a, hg, ag = r["HomeTeam"], r["AwayTeam"], int(r["FTHG"]), int(r["FTAG"])
        pts[h] += {"H": 3, "D": 1, "A": 0}[r["FTR"]]
        pts[a] += {"H": 0, "D": 1, "A": 3}[r["FTR"]]
        gd[h] += hg - ag
        gd[a] += ag - hg
        gf[h] += hg
        gf[a] += ag
        played[h] += 1
        played[a] += 1
    order = sorted(played, key=lambda t: (pts[t], gd[t], gf[t]), reverse=True)
    return order, pts, played

rows = []
for s in names:
    games = season(s)
    christmas = datetime(2000 + int(s[:2]), 12, 25)
    before, pts, played = table([r for r in games if r["date"] < christmas])
    final, _, _ = table(games)
    bottom, next_up = before[-1], before[-2]
    rows.append({"season": f"20{s[:2]}/{s[2:]}", "bottom": bottom, "played": played[bottom], "points": pts[bottom],
                 "gap": pts[next_up] - pts[bottom], "finish": final.index(bottom) + 1, "teams": len(final),
                 "second_bottom": next_up, "second_finish": final.index(next_up) + 1})

n = len(rows)
last = sum(r["finish"] == r["teams"] for r in rows)
eleventh = sum(r["finish"] == r["teams"] - 1 for r in rows)
print(f"{n} seasons: bottom on Christmas Day finished bottom {last} times, second-bottom {eleventh}, higher {n - last - eleventh}")
print(f"second-bottom on Christmas Day finished bottom {sum(r['second_finish'] == r['teams'] for r in rows)} times")
for r in rows:
    print(f"  {r['season']} {r['bottom']:16} {r['points']:2} pts from {r['played']:2}, {r['gap']:2} behind, finished {r['finish']}")
for label, group in (("level or 1 point behind", [r for r in rows if r["gap"] <= 1]), ("2 or more points behind", [r for r in rows if r["gap"] >= 2])):
    print(f"{label} the side above: {len(group)} seasons, finished bottom {sum(r['finish'] == r['teams'] for r in group)}, "
          f"bottom two {sum(r['finish'] >= r['teams'] - 1 for r in group)}")
```
