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;
Tạo ra kết quả mong muốn.
-
Viết lại bằng
JOINrõ ràng cú pháp. Giúp cho việc đọc và hiểu (và gỡ lỗi) trở nên dễ dàng hơn rất nhiều. -
Bằng cách kết hợp với nhiều
1:ncác bảng, các hàng có liên quan sẽ nhân nhau tạo ra sản phẩm Descartes - đó là điều vô nghĩa rất tốn kém. Đây là mộtCROSS JOINngoài ý muốn bằng proxy. Có liên quan: -
Để tránh điều này, hãy tham gia nhiều nhất một
n-chuyển tới1-bảng trước khi bạn tổng hợp (GROUP BY). Bạn có thể tổng hợp hai lần, nhưng tổng hợpnsẽ nhanh hơn và nhanh hơn -bảng riêng trước kết hợp họ với1-bàn. -
Trái ngược với bản gốc của bạn (với
INNER JOINngầm hiểu ). Tôi sử dụngLEFT JOINđể tránh mất các hàng từfookhông có hàng phù hợp trongfoo_barhoặc thẻtag. -
Sau khi
CROSS JOINkhông mong muốn được xóa khỏi truy vấn, không cần thêmDISTINCTnữa - giả sử rằngfoo.idlà duy nhất.