Вы можете сделать это с условным агрегированием:
SELECT
DATE_FORMAT(p.created_at,'%Y-%m') AS service_year_month,
COUNT(p.id) AS total_pickup_id,
SUM(p.material = 'PAPER') AS paper_pickups,
SUM(p.material = 'OTHER') AS other_pickups,
SUM(p.material = 'PLASTIC') AS plastic_pickups,
SUM(p.material = 'WOOD') AS wood_pickups,
SUM(p.material = 'GLAS') AS glas_pickups,
SUM(p.material = 'METAL') AS metal_pickups
FROM pickup p LEFT JOIN container c
ON p.container_id = c.id AND c.pickup_mode = 'ON_DEMAND'
GROUP BY service_year_month
ORDER BY service_year_month desc;
Также используйте псевдонимы для таблиц, чтобы сократить код и сделать его более читабельным. Я переместил условие:
c.pickup_mode = 'ON_DEMAND'
в предложение ON
, так как при использовании его в предложении WHERE
соединение заменяется на INNER JOIN
.