SELECT f.id, f.name, b.fb_ct, t.tag_names
FROM foo f
LEFT JOIN (
SELECT foo_id AS id, count(*) AS fb_ct
FROM foo_bar
GROUP BY 1
) b USING (id)
LEFT JOIN (
SELECT target_id AS id, array_agg(name) AS tag_names
FROM tag
GROUP BY 1
) t USING (id)
ORDER BY f.id;
Daje pożądany rezultat.
-
Przepisz z jawnym
JOINskładnia. Znacznie ułatwia czytanie i zrozumienie (i debugowanie). -
Łącząc się z wieloma
1:npowiązanych tabel, wiersze mnożą się nawzajem, tworząc produkt kartezjański - co jest bardzo kosztownym nonsensem. To niezamierzoneCROSS JOINprzez pełnomocnika. Powiązane: -
Aby tego uniknąć, dołącz co najwyżej do jednego
n-table do1-table przed agregacją (GROUP BY). Możesz agregować dwa razy, ale agregacjanjest czystsza i szybsza -tabele oddzielnie przed dołączanie ich do1-stół. -
W przeciwieństwie do oryginału (z niejawnym
INNER JOIN). UżywamLEFT JOINaby uniknąć utraty wierszy zfooktóre nie mają pasującego wiersza wfoo_barlubtag. -
Po niezamierzonym
CROSS JOINzostanie usunięty z zapytania, nie ma potrzeby dodawaniaDISTINCTwięcej - zakładając, żefoo.idjest wyjątkowy.