No, this is not a bug in MySQL.
Your JOIN conditions generate "duplicate" lines. (Remove aggregate functions and GROUP BY, and you will see what happens.
This row from table "a" corresponds to four rows from table "b". This is all beautiful and good. But when you add a join to the third table ("y"), each row returned from this third table "y" (two rows) is "mapped" to each row from table "b" ... so you keep in common complexity eight lines in your result set. (That's why the "total_count" doubles.)
To get the result set you specified, you do not need to join this table βbβ a second time. Instead, simply use a conditional test to determine whether to include this βscoreβ in βyβ or not.
eg.
SELECT a.id , SUM(b.count) AS total_count , SUM(IF(b.date=UTC_DATE()-1 ,b.count,0)) AS y FROM aa LEFT JOIN bb ON (b.a_id=a.id) GROUP BY a.id;
Note that the MySQL IF expression can be replaced with the equivalent ANSI CASE expression to improve portability:
, SUM(CASE WHEN b.date=UTC_DATE()-1 THEN b.count ELSE 0 END) AS y
If you want to make a JOIN in this "b" table for the second time, you need the JOIN condition to be such that the row from "y" matches at most one row from "b", so that no duplicates are entered. So you basically need a join condition to include all columns in the primary key.
(Note that the predicates in the join condition for table "y" ensure that each of "y" matches no more than one row from "b"):
SELECT a.id , SUM(b.count) AS total_count , SUM(y.count) AS y FROM aa LEFT JOIN bb ON b.a_id=a.id LEFT JOIN by ON y.a_id = b.a_id AND y.b_id = b.b_id AND y.date = b.date AND y.date = UTC_DATE()-1 GROUP BY a.id;
(To get the first statement to return an identical result set with potential NULL instead of zero, you need to replace the constant '0' in the IF expression with "NULL".
, SUM(IF(b.date=UTC_DATE()-1 ,b.count,NULL)) AS y