Because you SQL query need the ability to distinct subquery fields in order to treat it as a table type record source.
Here is an example of what's happen :
with table_1 as (select 0 A, 0 B, 0 C),
table_2 as (select 0 A, 0 D),
table_3 as (select 1 A, 0 B, 0 C)
SELECT *
FROM
(select *
from table_1 t1
join table_2 t2
on t1.A = t2.A
join table_3 t3
on t1.B = t3.B
and t1.C = t3.C) AS output_table
WHERE output_table.D = 0;
This fails because the subquery has field t1.A/t1.B/t1.C and t2.A/t2.D and t3.A/t3.B/t3.C.
If you don't make it a subquery, then the MySQL engine doesn't need to distinct the fields and can output records with all fields indistinctively.
From your case, the query that works :
with table_1 as (select 0 A, 0 B, 0 C),
table_2 as (select 0 A, 0 D),
table_3 as (select 1 A, 0 B, 0 C)
select *
from table_1 t1
join table_2 t2
on t1.A = t2.A
join table_3 t3
on t1.B = t3.B
and t1.C = t3.C;
So, to avoid the problem, select precisely what fields you requires from your subquery, like that :
with table_1 as (select 0 A, 0 B, 0 C),
table_2 as (select 0 A, 0 D),
table_3 as (select 1 A, 0 B, 0 C)
SELECT *
FROM
(select t1.*, t2.D
from table_1 t1
join table_2 t2
on t1.A = t2.A
join table_3 t3
on t1.B = t3.B
and t1.C = t3.C) AS output_table
WHERE output_table.D = 0;
To be more clear, imagine that you want to join another table with your subquery ((subquery) AS output_table join another_table t4 on t4.A = output_table.A, how the MySQL engine can determine which field A from output_table it should use to join with another_table between t1.A (0) and T3.A (1) ? It can't, unless you specify only one field 'A' in your subquery.
select *in the subquery. List the columns in the subquery.FROM (select * from.......) AS output_tableselect *. I think my earlier comment got all jumbled.