Consultas SQL com JOIN e COUNT: apresentando todos os registros de Região
Gabarito: letra D — apenas as assertivas I e II estão corretas. A assertiva I usa uma subconsulta correlacionada que conta os serviços por região, preservando todas as regiões; a assertiva II usa LEFT JOIN para incluir regiões sem serviços, retornando zero no COUNT; a assertiva III usa INNER JOIN, que exclui regiões sem serviços, contrariando o requisito de apresentar TODOS os registros de Região.
O problema central desta questão é a diferença entre INNER JOIN e LEFT JOIN (ou LEFT OUTER JOIN) quando se deseja preservar todas as linhas de uma tabela, mesmo aquelas sem correspondência na outra. O INNER JOIN retorna apenas as linhas que possuem correspondência em ambas as tabelas, descartando as demais. Já o LEFT JOIN retorna todas as linhas da tabela à esquerda (a primeira mencionada no FROM), preenchendo com NULL as colunas da tabela à direita quando não há correspondência. Essa distinção é crucial para relatórios que precisam listar todos os registros de uma entidade, mesmo aqueles sem associações.
No contexto do modelo ER, temos as entidades Regiao, Unidade, UnidadeServico e Servico, com relacionamentos que conectam uma região a várias unidades, cada unidade a vários serviços (via UnidadeServico, uma tabela associativa). O objetivo é contar, para cada região, quantos serviços estão associados. Se uma região não possui nenhuma unidade ou serviço, o INNER JOIN a excluiria do resultado, enquanto o LEFT JOIN a manteria, com o COUNT retornando 0 (pois COUNT ignora valores NULL).
A assertiva I aborda isso de forma diferente: usa uma subconsulta correlacionada. A subconsulta é executada para cada linha da consulta externa, e a correlação é feita pela condição WHERE R.reg_descricao = RE.reg_descricao. Isso garante que, para cada região da consulta externa, a subconsulta conte apenas os serviços daquela região. Como a consulta externa seleciona todas as regiões da tabela Regiao (aliás RE), todas as regiões aparecem no resultado, mesmo aquelas sem serviços (a subconsulta retornaria 0 ou NULL, que é aceitável conforme o enunciado).
A assertiva III, por outro lado, usa INNER JOIN em todas as junções. Isso significa que apenas regiões que possuem pelo menos uma unidade, que por sua vez possui pelo menos um serviço, aparecerão no resultado. Regiões sem serviços seriam excluídas, violando o requisito de apresentar TODOS os registros de Regiao. Portanto, a assertiva III está incorreta.
A assertiva II usa LEFT JOIN em todas as junções, o que preserva todas as regiões. O COUNT(US.ser_id) conta apenas os valores não nulos de ser_id, então regiões sem serviços terão contagem 0. Isso atende perfeitamente ao requisito.
A pegadinha da banca está em confundir o efeito do INNER JOIN com o do LEFT JOIN. O candidato pode achar que o INNER JOIN é suficiente, mas ele descarta registros sem correspondência. A assertiva I é mais sutil, pois usa uma subconsulta correlacionada, que é uma técnica válida para este caso, embora menos eficiente que o LEFT JOIN.
Assertiva | Técnica utilizada | Apresenta TODAS as regiões? | Contagem para regiões sem serviços | Correta? |
|---|
I | Subconsulta correlacionada | Sim (consulta externa sem filtro) | 0 ou NULL (aceitável) | ✅ |
II | LEFT JOIN em todas as junções
| Sim (preserva tabela à esquerda) | 0 (COUNT ignora NULL) | ✅ |
III | INNER JOIN em todas as junções
| Não (exclui regiões sem correspondência) | Não se aplica (região não aparece) | ❌ |
Assertiva I — ✅ Correta
A assertiva I está correta. Ela usa uma subconsulta correlacionada para contar os serviços por região. A consulta externa seleciona todas as regiões da tabela Regiao (aliás RE). Para cada região, a subconsulta é executada, contando os serviços associados àquela região, com a correlação feita pela condição WHERE R.reg_descricao = RE.reg_descricao. Como a consulta externa não tem filtro, todas as regiões aparecem no resultado. Para regiões sem serviços, a subconsulta retorna 0 (ou NULL, que é aceitável). O GROUP BY reg_descricao dentro da subconsulta é desnecessário, mas não invalida a consulta, pois a correlação já garante um único valor por região. Portanto, a assertiva atende ao requisito de apresentar todos os registros de Regiao.
Assertiva II — ✅ Correta
A assertiva II está correta. Ela usa LEFT JOIN em todas as junções, o que preserva todas as linhas da tabela Regiao (a tabela à esquerda). Para regiões sem unidades ou serviços, as colunas das tabelas à direita serão NULL. O COUNT(US.ser_id) conta apenas os valores não nulos, então regiões sem serviços terão contagem 0. O GROUP BY reg_descricao agrupa os resultados por região. Isso atende perfeitamente ao requisito de apresentar todos os registros de Regiao, com zero para aquelas sem serviços.
Assertiva III — ❌ Incorreta
A assertiva III está incorreta. Ela usa INNER JOIN em todas as junções. O INNER JOIN retorna apenas as linhas que possuem correspondência em ambas as tabelas. Portanto, regiões que não possuem nenhuma unidade ou serviço serão excluídas do resultado. Isso viola o requisito de apresentar TODOS os registros de Regiao. O COUNT(US.ser_id) contaria apenas os serviços das regiões que possuem associações, mas as regiões sem serviços simplesmente não apareceriam. Portanto, a assertiva III não atende ao requisito.
Gabarito: letra D — apenas as assertivas I e II estão corretas.