This is my final working code:
<?php
global $wpdb;
$sum = '0';
$results = $wpdb->get_results("SELECT SUM(x.total_invoice_cost) AS final ,CONCAT( YEAR(x.post_date), '-', MONTH(x.post_date) ) AS grandtotal
FROM (
SELECT ID, total_invoice_cost.meta_value AS total_invoice_cost, paid.meta_value AS paid, wp_posts.post_date
FROM wp_posts
LEFT OUTER JOIN
(SELECT post_id, meta_value FROM wp_postmeta WHERE meta_key='paid') paid
ON wp_posts.id=paid.post_id
LEFT OUTER JOIN
(SELECT post_id, meta_value, meta_key FROM wp_postmeta WHERE meta_key='total_invoice_cost') total_invoice_cost
ON wp_posts.id=total_invoice_cost.post_id
) x
WHERE x.total_invoice_cost IS NOT NULL AND x.paid='yes' GROUP BY CONCAT( YEAR(x.post_date), '-', MONTH(x.post_date)
)");
if(!empty($results)) {
foreach($results as $r) {
echo "<p>".$r->grandtotal."</p>";
echo "<p>£".$r->final."</p>";
}
} else {
echo "<p>No invoices this month!</p>";
}
?>
It outputs like this:
2015-4
£100
2015-3
£50
I'm not sure if this is secure and/or open to SQL injections etc. I would appreciate it if someone could check it over and make sure it is all correct. :)