Eu estou um pouco preso a um pouco de SQL. Acho que não consigo formular a pergunta de maneira brilhante - deixe-me mostrar a você.
Tenho duas mesas, uma chamada pessoa e outra chamada compromisso. Estou tentando retornar o número de compromissos de uma pessoa (inclusive se eles tiverem zero). O compromisso contém o person_id
e há um person_id
por compromisso. Portanto, COUNT(person_id)
é uma abordagem sensata.
A pergunta:
SELECT person_id, COUNT(person_id) AS "number_of_appointments"
FROM appointment
GROUP BY person_id;
Retornará corretamente, o número de compromissos que um person_id possui. No entanto, uma pessoa que tem 0 compromissos não é devolvida (obviamente porque não está naquela mesa).
Ajustar a instrução para retirar person_id da tabela de pessoas me dá algo como:
SELECT person.person_id, COUNT(appointment.person_id) AS "number_of_appointments"
FROM appointment
JOIN person ON person.person_id = appointment.person_id
GROUP BY person.person_id;
No entanto, isso ainda retornará apenas um person_id que tenha um compromisso e não o que eu quero que é um retorno com pessoas que não tenham nenhum compromisso!
Alguma sugestão, por favor?
fonte
Respostas:
Você quer uma junção externa para isso (e você precisa usar pessoa como a mesa "motriz")
O motivo pelo qual isso está funcionando é que a junção externa (esquerda) retornará
NULL
para aquelas pessoas que não têm um compromisso. A função de agregaçãocount()
não contaráNULL
valores e, portanto, você obterá um zero.Se você quiser aprender mais sobre junções externas, aqui está um bom tutorial: http://sqlzoo.net/wiki/Using_Null
fonte
Você deve usar em
LEFT JOIN
vez deINNER JOIN
fonte
se você fizer a junção externa (com a contagem) e, em seguida, usar este resultado como uma subtabela, você pode obter 0 conforme o esperado (graças à função nvl)
Ex:
fonte
USE join para obter 0 contagem no resultado usando GROUP BY.
simplesmente 'join' faz o Inner join no MS SQL, então, vá para left ou right join.
Se a tabela que contém a chave primária for mencionada primeiro na QUERY, use a junção LEFT, senão a junção RIGHT.
POR EXEMPLO:
.
Pegue o agrupamento da mesa que possui a chave primária e conte a partir da outra mesa que possui entradas / detalhes reais.
fonte
Para alterar ainda menos sua consulta original, você pode transformar sua associação em uma
RIGHT
associaçãoIsso apenas se baseia na resposta selecionada, mas como a junção externa está na
RIGHT
direção, apenas uma palavra precisa ser adicionada e menos alterações. - Lembre-se de que ele está lá e, às vezes, pode tornar as consultas mais legíveis e exigir menos reconstrução.fonte
O problema com LEFT JOIN é que se não houver compromissos, ele ainda retornará uma linha com um valor nulo, que quando agregado por COUNT se tornará 1, e parecerá que a pessoa tem um compromisso quando na verdade não tem nenhum. Acho que isso dará os resultados corretos:
fonte