SELECT year_id, location_id, figure_id, value
FROM fact_data -- ###MAGIC###
WHERE figure_id IN ("total_costs", "purchase_costs",
"goods_costs")
AND year_id = 2010;
is fine, especially if fact_data has
INDEX(year_id, figure_id)
So, perhaps your example was not complex enough??
We need to see SHOW CREATE TABLE for the tables in question. We especially need to know the PRIMARY KEY of fact_data.
This subquery begs for an artificial
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY
SELECT a.year_id, a.location_id, "purchase_costs",
a.value + b.value * c.value
FROM fact_data a
LEFT JOIN fact_data b ON a.year_id = b.year_id
AND a.location_id = b.location_id
AND b.figure_id = "admin_costs_purchase_dist"
LEFT JOIN fact_data c ON a.year_id = c.year_id
AND a.location_id = c.location_id
AND c.figure_id = "admin_costs"
WHERE a.figure_id = "goods_costs"
LEFT JOIN is the way to deal with NULLs; no UNION needed (or maybe I do not understand what you are doing).