Para simplificar sua lógica, agregue primeiro, junte-se depois.
Adivinhar detalhes ausentes, essa consulta forneceria a contagem exata, quantas vezes cada usuário foi referenciado em
table1
e table2
respectivamente para todos os usuários :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);
Em particular, evite múltiplos relacionamentos 1-n se multiplicando quando unidos:
Para recuperar um único ou poucos usuários somente,
LATERAL
as junções serão mais rápidas (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;
Explique a diferença percebida
A incompatibilidade específica que você relata deve-se às especificidades de um
FULL OUTER JOIN
:Assim, você obtém valores NULL anexados no outro lado respectivo para correspondências ausentes.
count()
não conta valores NULL. Assim, você pode obter um resultado diferente dependendo de filtrar em u1.id=100
ou u2.id=100
. Isso é apenas para explicar, você não precisa de um
FULL JOIN
aqui. Use as alternativas apresentadas.