Ваша попытка использования full join
находится на правильном пути; к сожалению, MySQL не поддерживает этот синтаксис.
Вы можете сделать это с union all
и условным агрегированием:
select
date,
sum(what = 'pens') no_pens,
sum(what = 'pencils') no_pencils,
sum(what = 'ink') no_inks
from (
select 'pens' what, date from pens
union all select 'pencils', date from pencils
union all select 'ink', date from ink
) t
group by date
Если вы хотите, чтобы все даты, включая те, для которых нет продажи случилось для любого продукта, то это немного по-другому. Для этого вам нужен календарь. Вот один из способов сделать это с помощью рекурсивного запроса (доступно только в MySQL 8.0).
with dates as (
select min(date) date, max(date) max_date
from (
select date from pens
union all select date from pencils
union all select date from ink
) t
union all
select date + interval 1 day from cte where date < max_date
)
select
d.date,
pn.no_pens,
pl.no_pencils,
ik.no_inks
from dates d
left join (select date, count(*) no_pens from pens group by date) pn on pn.date = d.date
left join (select date, count(*) no_pencils from pencils group by date) pl on pl.date = d.date
left join (select date, count(*) no_inks from inks group by date) ik on ik.date = d.date