Non vedo alcun motivo per cui dovresti usare una sottoquery. Credo che tu possa semplicemente combinare fi_business
e fi_business_subcategory
a un singolo fattore di tabella tra parentesi.
SELECT
c.id,
c.name,
c.slug,
sc.id,
sc.name,
sc.slug,
COUNT(bsc.id) AS business_count
FROM
fi_category c
LEFT JOIN
fi_subcategory sc ON c.id = sc.category_id AND (sc.deleted_at IS NULL)
LEFT JOIN (
fi_business b
INNER JOIN
fi_business_subcategory bsc ON b.id = bsc.business_id AND (bsc.deleted_at IS NULL)
INNER JOIN
fi_suburb su ON su.id = b.suburb_id AND su.city_id = 1
) ON sc.id = bsc.subcategory_id
WHERE
(c.deleted_at IS NULL)
GROUP BY
c.id, sc.id
Ho controllato che questo è un SQL valido per la struttura della tua tabella. Immagino che ci siano buone probabilità che produca il risultato desiderato, anche se il tuo violino non contiene ancora dati. Vedi il manuale sulla sintassi JOIN per i dettagli su dove puoi usare le parentesi in un join.
Potresti anche chiederti se hai davvero bisogno che tutti i join siano left join. Scrivere cose usando inner join sarebbe molto più semplice.
Poiché i join vengono eseguiti da sinistra a destra, potresti eseguire prima i join interni, seguiti da una sequenza di destra si unisce. Questo evita le parentesi:
SELECT
c.id cat_id,
c.name cat_name,
c.slug cat_slug,
sc.id sub_id,
sc.name sub_name,
sc.slug sub_slug,
COUNT(bsc.id) AS business_count
FROM
fi_business b
INNER JOIN
fi_business_subcategory bsc ON b.id = bsc.business_id
AND (b.deleted_at IS NULL) AND (bsc.deleted_at IS NULL)
INNER JOIN
fi_suburb su ON su.id = b.suburb_id AND su.city_id = 1
RIGHT JOIN
fi_subcategory sc ON sc.id = bsc.subcategory_id
RIGHT JOIN
fi_category c ON c.id = sc.category_id AND (sc.deleted_at IS NULL)
WHERE
(c.deleted_at IS NULL)
GROUP BY
c.id, sc.id