Considere as tabelas USUARIO(id_usuario, nome) e CHAMADO(i...

Próximas questões
Com base no mesmo assunto
Q4378050 Banco de Dados
Considere as tabelas USUARIO(id_usuario, nome) e CHAMADO(id_chamado, id_usuario, status), sendo CHAMADO.id_usuario chave estrangeira para USUARIO.id_usuario. Um relatório deve listar todos os usuários, inclusive aqueles que nunca abriram chamado, e apresentar a quantidade de chamados de cada um, exibindo zero quando não houver registros. 
Desconsideradas particularidades sintáticas de SGBDs específicos, qual consulta atende ao requisito? 
Alternativas

Gabarito comentado

Confira o gabarito comentado por um dos nossos professores

Gabarito: B

Fundamento decisivo: Como o relatório exige todos os usuários e zero chamados para quem não tem registros, a consulta deve preservar USUARIO sem contar como chamado a linha gerada pela junção. A alternativa B atende a esse critério.

Tema central: Junção externa e contagem
Análise das alternativas
A
Errada
O INNER JOIN mantém somente as correspondências entre USUARIO e CHAMADO. Assim, um usuário sem chamados é eliminado antes do agrupamento e não aparece no relatório. O requisito exige preservar esse usuário, não apenas contar os chamados daqueles que possuem correspondência.
B
Certa
Na alternativa B, USUARIO está à esquerda do LEFT JOIN, de modo que todos os usuários permanecem no resultado, mesmo sem chamados. Para esses usuários, as colunas de CHAMADO recebem NULL. O GROUP BY u.id_usuario, u.nome forma um grupo por usuário, e COUNT(c.id_chamado) conta os valores não nulos do identificador de chamado: havendo chamados, obtém-se sua quantidade; sem correspondência, a contagem retorna zero, não NULL, dispensando COALESCE. O gabarito pressupõe que id_chamado seja não nulo nos chamados existentes, conforme seu papel convencional de identificador. Essa restrição não foi explicitada no enunciado; se chamados reais tiverem esse campo NULL, eles não serão contados.
C
Errada
O LEFT JOIN preserva a tabela à esquerda, que nesta consulta é CHAMADO. Um usuário sem chamados não tem uma linha nessa tabela a partir da qual possa ser incluído no resultado. Portanto, embora COUNT(c.id_chamado) seja a forma de contagem pretendida, a consulta preserva o lado errado da relação.
D
Errada
O LEFT JOIN preserva corretamente todos os usuários, mas COUNT(*) conta as linhas do resultado da junção. Para um usuário sem chamados, permanece uma linha com as colunas de CHAMADO preenchidas por NULL; essa linha também é contada. Por isso, a consulta exibe um em vez de zero. Era necessário contar uma expressão do chamado que desconsiderasse os NULL gerados pela ausência de correspondência.
E
Errada
O RIGHT JOIN preserva a tabela à direita, que é CHAMADO, e não USUARIO. Dessa forma, usuários sem chamados não são mantidos no resultado. A contagem dos identificadores não corrige essa falha: ela agrega as linhas disponíveis, mas não inclui os usuários que a junção deixou de preservar.
Pegadinha da questão
A presença de LEFT JOIN pode dar a impressão de que o requisito já está atendido. A alternativa D explora justamente essa confusão: preservar o usuário sem chamado não significa que a linha preservada deva ser contada como um chamado.
Dica para questões semelhantes
  • Confira qual tabela ocupa o lado preservado da junção: à esquerda no LEFT JOIN e à direita no RIGHT JOIN. O nome da junção, isoladamente, não determina quais entidades serão mantidas.
  • Não deduza da chave estrangeira que todo registro da tabela referenciada possui registros associados: ela não obriga cada usuário a ter chamado.

Clique para visualizar este gabarito

Visualize o gabarito desta questão clicando no botão abaixo