Để đơn giản hóa logic của bạn, hãy tổng hợp trước, kết hợp sau.
Đoán các chi tiết còn thiếu, truy vấn này sẽ cung cấp cho bạn số lượng chính xác, số lần mỗi người dùng được tham chiếu trong table1
và table2
tương ứng cho tất cả người dùng :
SELECT *
FROM users u
LEFT JOIN (
SELECT updated_by_id AS id, count(*) AS t1_ct
FROM table1
GROUP BY 1
) t1 USING (id)
LEFT JOIN (
SELECT updated_by_id AS id, count(*) AS t2_ct
FROM table2
GROUP BY 1
) t2 USING (id);
Đặc biệt, tránh nhiều mối quan hệ 1-n nhân với nhau khi kết hợp với nhau:
Để truy xuất một hoặc một vài người dùng chỉ, LATERAL
tham gia sẽ nhanh hơn (Postgres 9.3+):
SELECT *
FROM users u
LEFT JOIN LATERAL (
SELECT count(*) AS t1_ct
FROM table1
WHERE updated_by_id = u.id
) ON true
LEFT JOIN LATERAL (
SELECT count(*) AS t2_ct
FROM table2
WHERE updated_by_id = u.id
) ON true
WHERE u.id = 100;
Giải thích sự khác biệt nhận thức được
Sự không khớp cụ thể mà bạn báo cáo là do các chi tiết cụ thể của FULL OUTER JOIN
:
Vì vậy, bạn nhận được các giá trị NULL được thêm vào ở phía bên kia tương ứng cho các kết quả khớp bị thiếu. count()
không tính giá trị NULL. Vì vậy, bạn có thể nhận được một kết quả khác tùy thuộc vào việc bạn có lọc trên u1.id=100
hay không hoặc u2.id=100
.
Điều này chỉ để giải thích, bạn không cần FULL JOIN
nơi đây. Thay vào đó, hãy sử dụng các lựa chọn thay thế được trình bày.