Case study · Data & BI · 5 min read
Irish property prices
An SQL analysis of every residential sale on Ireland's Property Price Register from January 2010 to October 2026, asking how prices and sales have changed and where they have moved most.
- Role
- Solo project. All the analysis is SQL run in DuckDB. Python only downloads the file, runs the SQL in order and draws the charts.
- Type
- Data & BI
- Stack
- SQL, DuckDB, Python, pandas, matplotlib
Show the numbers as a table
| Year | Dublin | Rest of Ireland | Ratio |
|---|---|---|---|
| 2010 | €277,500 | €188,410 | 1.47 |
| 2011 | €250,000 | €154,550 | 1.62 |
| 2012 | €215,650 | €130,000 | 1.66 |
| 2013 | €235,000 | €119,175 | 1.97 |
| 2014 | €261,420 | €118,000 | 2.22 |
| 2015 | €280,000 | €130,000 | 2.15 |
| 2016 | €312,611 | €145,000 | 2.16 |
| 2017 | €341,665 | €166,845 | 2.05 |
| 2018 | €360,000 | €185,000 | 1.95 |
| 2019 | €360,000 | €200,000 | 1.80 |
| 2020 | €375,000 | €203,000 | 1.85 |
| 2021 | €390,000 | €225,000 | 1.73 |
| 2022 | €420,000 | €253,000 | 1.66 |
| 2023 | €430,000 | €275,000 | 1.56 |
| 2024 | €471,252 | €300,000 | 1.57 |
| 2025 | €498,999 | €335,000 | 1.49 |
- 812,018sales after cleaning (from 813,106 rows)
- €380,000national median in 2025, up from €148,000 in 2013
- €498,999Dublin median in 2025, against €335,000 elsewhere
- 1.49xDublin to rest of Ireland in 2025, down from 2.22x in 2014
- 12.6%of a year's sales close in December, on average
01
Problem
The Property Price Register lists every home sold in Ireland since 2010 with its price, date, address and county. I wanted to see what it says about the market once the data is cleaned properly.
Headlines quote one number for house prices, but the picture is very different in Dublin, in the commuter counties and in the west. The raw file is also awkward: prices stored as text, dates as DD/MM/YYYY, Irish and English descriptions, and VAT left out on most new homes.
The question: how have prices and sales changed since 2010, and where in the country have they moved most?
02
What I did
- Eight numbered SQL files, one per question: load and clean, yearly overview, counties, Dublin against the rest, new against second-hand, seasonality, rolling medians and data quality.
- Cleaning in SQL. The file is read as Windows-1252 so the euro sign survives, prices are stripped to digits with regexp_replace, dates go through try_strptime so bad rows can be counted instead of crashing the query, and 1,088 exact duplicates are removed.
- Non-market sales (41,190) and prices under €10,000 or over €10m (1,284) stay in the sales table but are left out of a single market_sales view, so every price query uses the same rules.
- VAT is added back at 13.5% on new homes recorded without it. Without that step the 2025 new-home median would read €387,665 instead of €440,000.
- CTEs build each query in readable steps. Window functions do the rest: LAG for year-on-year change, RANK for county order and the busiest month, PARTITION BY for each month's share of its year, and a 12-month rolling median using RANGE over dates.
- Fifteen data-quality checks stacked with UNION ALL into one report, plus pytest checks on the cleaning logic that run on a 1,000-row sample.
Decisions along the way
- Medians, not means
- A few homes sell for millions and drag the average up. In 2025 the mean was €434,741 and the median €380,000. The CSO and Daft report medians for the same reason.
- Filter once, in a view
- Non-market and extreme sales are left out in the market_sales view instead of in each query, so no query can forget the filter.
- A rolling median over all sales
- The 12-month median is taken over every sale in the window, not as a median of 12 monthly medians, which would give quiet months as much weight as busy ones.
- Keep the outliers
- 1.7% of market sales sit above Q3 + 3 x IQR. They stay in, because a €1.5m house in Dublin 4 is real, and the median handles them.
Stack
- Analysis
- SQL in DuckDB
- Glue
- Python runs the SQL files in order and saves results with pandas
- Charts
- matplotlib
- Tests
- pytest on a 1,000-row sample
- Data
- Residential Property Price Register (PSRA), downloaded 26 Oct 2026
03
What I found
- The national median sale price was €380,000 in 2025, up from a low of €148,000 in 2013 (+157%) and well above the 2010 level of €215,650.
- Growth is slowing. The rolling 12-month median reached €395,000 by October 2026, up 5.3% on a year earlier, down from a peak of 11.3% in May 2025.
- Dublin is still the dearest county at €498,999, but the rest of the country is catching up. A Dublin home cost 2.22 times the median elsewhere in 2014 and 1.49 times in 2025. In euro the gap has stayed at about €150,000 to €175,000 since 2016.
- Smaller, cheaper counties rose fastest after 2020. Sligo's median more than doubled (+107%, €122,500 to €254,000), with Leitrim (+96%) and Roscommon (+91%) close behind. Dublin rose least (+33%).
- New homes were 22.9% of sales in 2025, up from 12.3% in 2013, and their premium over second-hand homes fell from 55.6% in 2020 to 27.5% (€440,000 against €345,000).
- December is by far the busiest month for completed sales: 12.6% of a year's sales on average, against 5.6% in January. It was the busiest month in 15 of the 16 full years.
More charts
National median and number of sales
New against second-hand homes
Median sale price by county, 2025
- Dublin€498,999
- Wicklow€450,505
- Kildare€440,000
- Meath€405,000
- Cork€370,000
- Galway€365,000
- Louth€360,000
- Kilkenny€340,000
- Limerick€320,000
- Westmeath€320,000
- Laois€317,000
- Waterford€300,500
- Wexford€300,000
- Clare€300,000
- Kerry€285,000
- Offaly€276,000
- Carlow€271,500
- Tipperary€257,250
- Sligo€254,000
- Cavan€245,000
- Monaghan€240,000
- Mayo€220,000
- Leitrim€200,000
- Roscommon€200,000
- Donegal€186,000
- Longford€185,000
What I learned
- Most of the work is in the cleaning. The encoding, the text prices and the VAT each changed the answer before any analysis started.
- Window functions let one query answer questions that would otherwise need several, like each month's share of its own year.
- Writing the data-quality checks as a query of their own makes it easy to say what the data cannot answer.
04
The SQL
WITH labelled AS (
SELECT sale_year,
CASE WHEN county = 'Dublin' THEN 'Dublin' ELSE 'Rest of Ireland' END AS region,
price_incl_vat
FROM market_sales
),
by_region AS (
SELECT sale_year, region, count(*) AS sales, median(price_incl_vat) AS median_price
FROM labelled
GROUP BY sale_year, region
),
side_by_side AS (
-- Conditional aggregation turns two rows into two columns
SELECT sale_year,
max(CASE WHEN region = 'Dublin' THEN median_price END) AS dublin_median,
max(CASE WHEN region = 'Rest of Ireland' THEN median_price END) AS rest_median
FROM by_region
GROUP BY sale_year
)
SELECT sale_year,
round(dublin_median) AS dublin_median_eur,
round(rest_median) AS rest_median_eur,
round(dublin_median / rest_median, 2) AS dublin_to_rest_ratio
FROM side_by_side
ORDER BY sale_year;What it answers
How big is the price gap between Dublin and the rest of the country, and has it grown or shrunk since 2010?
First 5 rows
| sale_year | dublin_median_eur | rest_median_eur | ratio |
|---|---|---|---|
| 2010 | €277,500 | €188,410 | 1.47 |
| 2011 | €250,000 | €154,550 | 1.62 |
| 2012 | €215,650 | €130,000 | 1.66 |
| 2013 | €235,000 | €119,175 | 1.97 |
| 2014 | €261,420 | €118,000 | 2.22 |
From results/04_dublin_vs_rest.csv, run in DuckDB.
05
What I'd do next
- Compare the medians with the CSO's price index, which adjusts for the mix of homes sold.
- Rerun the queries once late filings for 2026 are in, since recent months can be revised upwards.
06
Limitations
- These are sale prices declared for stamp duty, not asking prices, so the register says nothing about bidding wars.
- VAT is added back at the standard 13.5% residential rate wherever the flag says the price excludes it. That assumes the rate applied to every such sale.
- Sales are dated when they closed, not when they were agreed, and late filings mean recent months can be revised upwards. 2026 is a part year, so 2025 is the latest full year.
- There is no floor area (size bands exist for only 6.5% of rows), no bedrooms and no house or apartment split, so a rising median can partly reflect a change in what was sold. The CSO's price index adjusts for that mix.
- Some bulk deals slip past the filters, and 287 addresses name a different county from the county column.
- The register is a guide only. The PSRA makes it available for re-use and its data on data.gov.ie is under CC BY 4.0. The raw file is not in the repo; a script downloads it.