As junções são processadas da esquerda para a direita (a menos que os parênteses indiquem o contrário). Se você
LEFT JOIN
(ou apenas JOIN
, efeito semelhante) três mantimentos para um usuário, você obtém 3 linhas (1 x 3 ). Se você entrar em 4 peixarias para o mesmo usuário, receberá 12 (3 x 4 ) linhas, multiplicando a contagem anterior no resultado, não adicionando para ele, como você pode ter esperado.Multiplicando assim as visitas para mantimentos e peixarias.
Você pode fazer funcionar assim:
SELECT u.id
, u.account_balance
, g.grocery_visits
, f.fishmarket_visits
FROM users u
LEFT JOIN (
SELECT user_id, count(*) AS grocery_visits
FROM grocery
GROUP BY user_id
) g ON g.user_id = u.id
LEFT JOIN (
SELECT user_id, count(*) AS fishmarket_visits
FROM fishmarket
GROUP BY user_id
) f ON f.user_id = u.id
ORDER BY u.id;
Para obter valores agregados para um ou poucos usuários, subconsultas correlacionadas como @Vince fornecidos estão bem. Para uma tabela inteira ou partes principais dela, é (muito) mais eficiente agregar as n-tabelas e juntar ao resultado uma vez . Dessa forma, também não precisamos de outro
GROUP BY
na consulta externa. grocery_visits
e fishmarket_visits
são NULL
para usuários sem entradas relacionadas nas respectivas tabelas. Se você precisar de 0
em vez disso (ou qualquer número arbitrário), use COALESCE
no SELECT
externo :SELECT u.id
, u.account_balance
, COALESCE(g.grocery_visits , 0) AS grocery_visits
, COALESCE(f.fishmarket_visits, 0) AS fishmarket_visits
FROM ...