J'opterais pour quelque chose comme :
SELECT
c.id AS campaign_id,
COUNT(cc.id) AS code_count
FROM
campaigns c
LEFT JOIN campaign_codes cc on cc.campaign_id = c.id
AND cc.status = 0 -- Having this clause in the WHERE, effectively makes this an INNER JOIN
WHERE c.partner_id = 4
GROUP BY c.id
Déplacer le AND
à la clause join fait réussir ou échouer la jointure, en conservant de manière cruciale les lignes résultantes là où il n'y a pas de ligne correspondante dans la "bonne" table.
Si c'était dans le WHERE
, les comparaisons avec NULL (où il n'y a pas de code_campagne) échoueraient et seraient éliminées des résultats.