MySQL se junta e COUNT (*) de outra tabela
Pergunta
Eu tenho duas tabelas: groups
e group_members
.
A tabela groups
contém todas as informações de cada grupo, como ID, título, descrição etc.
Na tabela group_members
, ela lista todos os membros que estão separados de cada grupo assim:
group_id | user_id
1 | 100
2 | 23
2 | 100
9 | 601
Basicamente, quero listar TRÊS grupos em uma página e só quero listar grupos que tenham MAIS de quatro membros.Dentro do loop <?php while ?>
, desejo então quatro membros que não fazem parte desse grupo.Não estou tendo problemas para listar os grupos e listar os membros em outro loop interno, simplesmente não posso refinar os grupos para que APENAS aqueles com mais de 4 membros apareçam.
Alguém sabe fazer isso?Tenho certeza que é com junções do MySQL.
Solução
MySQL usa a instrução HAVING para essas tarefas.
Sua consulta ficaria assim:
SELECT g.group_id, COUNT(m.member_id) AS members
FROM groups AS g
LEFT JOIN group_members AS m USING(group_id)
GROUP BY g.group_id
HAVING members > 4
exemplo quando as referências têm nomes diferentes
SELECT g.id, COUNT(m.member_id) AS members
FROM groups AS g
LEFT JOIN group_members AS m ON g.id = m.group_id
GROUP BY g.id
HAVING members > 4
Além disso, certifique-se de definir índices dentro do esquema do banco de dados para as chaves que está usando em JOINS, pois isso pode afetar o desempenho do seu site.
Outras dicas
SELECT DISTINCT groups.id,
(SELECT COUNT(*) FROM group_members
WHERE member_id = groups.id) AS memberCount
FROM groups
Sua tabela groups_main
tem uma coluna-chave chamada id
.Eu acredito que você só pode usar a sintaxe USING
para a junção se a tabela groups_fans
tiver uma coluna-chave com o mesmo nome, o que provavelmente não tem.Então, em vez disso, tente isto:
LEFT JOIN groups_fans AS m ON m.group_id = g.id
Ou substitua group_id
por qualquer nome de coluna apropriado na tabela groups_fans
.
Talvez eu esteja errado aqui e não entendo o OP, mas por que você está entrando nas mesas?
Se você tem uma tabela com membros e esta tem uma coluna chamada "group_id", você pode simplesmente executar uma consulta na tabela de membros para obter uma contagem dos membros agrupados pelo group_id.
SELECT group_id, COUNT(*) as membercount
FROM members
GROUP BY group_id
HAVING membercount > 4
Isso deve ter a menor sobrecarga simplesmente porque você está evitando uma junção, mas ainda assim deve dar o que você deseja.
Se você quiser os detalhes e a descrição do grupo, etc., adicione uma junção da tabela de membros de volta à tabela de grupos para recuperar o nome e lhe daria o resultado mais rápido.