За да опростите логиката си, първо обединете, присъединете се по-късно.
Отгатвайки липсващи подробности, тази заявка ще ви даде точния брой, колко пъти всеки потребител е бил споменат в table1
и table2
съответно за всички потребители :
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);
По-специално, избягвайте множество 1-n релации, които се умножават една друга, когато са обединени:
За да извлечете един или няколко потребители само, LATERAL
присъединяванията ще бъдат по-бързи (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;
Обяснете възприеманата разлика
Конкретното несъответствие, за което съобщавате, се дължи на спецификата на FULL OUTER JOIN
:
Така че получавате NULL стойности, добавени към съответната друга страна за липсващи съвпадения. count()
не отчита NULL стойности. Така че можете да получите различен резултат в зависимост от това дали филтрирате по u1.id=100
или u2.id=100
.
Това е само за обяснение, нямате нужда от FULL JOIN
тук. Вместо това използвайте представените алтернативи.