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;
वांछित परिणाम देता है।
-
स्पष्ट
JOIN
के साथ फिर से लिखें वाक्य - विन्यास। इसे पढ़ना और समझना (और डीबग करना) इतना आसान बनाता है। -
कई
1:n
. से जुड़कर संबंधित तालिकाएँ, पंक्तियाँ एक दूसरे को गुणा करके एक कार्टेशियन उत्पाद बनाती हैं। - जो बहुत महंगी बकवास है। यह एक अनपेक्षितCROSS JOIN
है परोक्ष रूप से। संबंधित: -
इससे बचने के लिए, अधिक से अधिक एक में शामिल हों
n
-टेबल से1
-टेबल आपके एकत्र होने से पहले (GROUP BY
) आप दो बार एकत्र कर सकते हैं, लेकिन यह अधिक स्वच्छ और समेकित करने के लिए तेज़ हैn
-टेबल अलग से पहले उन्हें1
. में शामिल करना -मेज़। -
आपके मूल के विपरीत (अंतर्निहित
INNER JOIN
. के साथ ) मैंLEFT JOIN
. का उपयोग करता हूंfoo
. से पंक्तियों को खोने से बचने के लिए जिसकीfoo_bar
. में कोई मेल खाने वाली पंक्ति नहीं है याtag
। -
एक बार अनजाने में
CROSS JOIN
क्वेरी से हटा दिया गया है,DISTINCT
जोड़ने की कोई आवश्यकता नहीं है और भी - यह मानते हुए किfoo.id
अद्वितीय है।