Analista - Perfil 8 - TI / Sistemas e Desenvolvimento - Tarde
William está trabalhando com a base de dados de uma clínica, onde estão presentes as entidades descritas a seguir.Paciente (Id: Integer PK,Nome: Varchar(50))Medico (Id: Integer PK, Nome: Varchar(50))Atendimento (Id: Integer PK,IdPaciente: Integer FK(Paciente),IdMedico: Integer FK(Medico),Data: Date)Para que William obtenha os nomes dos pacientes que foram tratados por todos os médicos, a instrução SQL a ser utilizada é:
Aselect p.nome from paciente p, atendimento awhere a.idpaciente = p.idand a.idmedico = all (select id from medico);
Bselect p.nome from paciente p where not exists (select id from medico m where id not in (select idmedico from atendimento where idpaciente = p.id));
Cselect p.nome from paciente p where exists (select idmedico from atendimento where idpaciente = p.id);
Dselect p.nome from paciente p, atendimento awhere a.idpaciente=p.id group by p.nomehaving count(*) = (select count(*) from medico);
Eselect p.nome from paciente p, atendimento awhere a.idpaciente = p.id anda.idmedico = any (select id from medico);
Revelar gabarito e comentário▾
GabaritoB — select p.nome from paciente p where not exists (
select id from medico m where id not in (
select idmedico from atendimento where idpaciente = p.id));
Comentário gerado por IA. É um apoio ao estudo, ancorado em fontes, mas pode conter imprecisões — confira sempre na fonte oficial (lei, súmula, edital e gabarito da banca). Encontrou um erro? Use “Reportar”.
Divisão relacional em SQL (pacientes tratados por todos os médicos)
Gabarito: letra B. A consulta correta utiliza a dupla negação (NOT EXISTS) para implementar a divisão relacional: seleciona pacientes para os quais não existe médico que não tenha realizado atendimento. Esse padrão equivale à lógica “para todo X, existe Y” e é o único que garante a obtenção dos pacientes que foram tratados por todos os médicos.
A questão testa o conhecimento de como expressar uma operação de divisão em SQL, um tema clássico de bancos de dados relacionais. A tabela Atendimento relaciona pacientes e médicos; o objetivo é encontrar pacientes que possuem ao menos um registro com cada médico.
Alternativa
Descrição
Correta?
Motivo
A
a.idmedico = ALL (SELECT id FROM medico)
❌
Compara um único valor com todos os IDs; impossível ser verdade (exceto se houver um só médico).
B
Dupla negação (NOT EXISTS com NOT IN)
✅
Implementa a divisão relacional: seleciona pacientes para os quais não existe médico que não tenha atendido.
C
EXISTS (SELECT idmedico FROM atendimento WHERE idpaciente = p.id)
❌
Retorna pacientes com pelo menos um atendimento, não todos os médicos.
D
GROUP BY ... HAVING COUNT(*) = (SELECT COUNT(*) FROM medico)
❌
Conta total de registros, não médicos distintos; paciente com múltiplas consultas ao mesmo médico falseia o resultado.
E
a.idmedico = ANY (SELECT id FROM medico)
❌
Equivale a IN; retorna pacientes que foram atendidos por pelo menos um médico, não todos.
Alternativa A — ❌ Incorreta
Usa a.idmedico = ALL (SELECT id FROM medico). Essa condição compara um único valor (o idmedico de uma linha da junção) com o conjunto de todos os id de médicos. Para ser verdadeira, aquela linha específica deveria ter um idmedico que fosse igual a todos os ids simultaneamente – o que é impossível (a menos que haja um só médico). Não realiza a divisão.
Alternativa B — ✅ Correta ⟵ GABARITO
SELECT p.nome FROM paciente p WHERE NOT EXISTS (SELECT id FROM medico m WHERE id NOT IN (SELECT idmedico FROM atendimento WHERE idpaciente = p.id)). Essa é a forma clássica: para cada paciente, verifica se não existe um médico que não tenha atendido aquele paciente. Se a subconsulta retornar vazia, significa que o paciente foi atendido por todos. Correta.
Alternativa C — ❌ Incorreta
SELECT p.nome FROM paciente p WHERE EXISTS (SELECT idmedico FROM atendimento WHERE idpaciente = p.id). Retorna pacientes que possuem pelo menos um atendimento (qualquer médico), não todos. Não atende ao requisito.
Alternativa D — ❌ Incorreta
SELECT p.nome FROM paciente p, atendimento a WHERE a.idpaciente=p.id GROUP BY p.nome HAVING COUNT(*) = (SELECT COUNT(*) FROM medico). Conta o número total de registros de atendimento por paciente, não o número de médicos distintos. Um paciente que visitou o mesmo médico várias vezes teria COUNT(*) maior que o número de médicos, falseando o resultado. Além disso, a junção implícita sem DISTINCT não impede duplicatas.
Alternativa E — ❌ Incorreta
SELECT p.nome FROM paciente p, atendimento a WHERE a.idpaciente = p.id AND a.idmedico = ANY (SELECT id FROM medico). Equivale a IN: retorna pacientes que tiveram atendimento com algum médico (pelo menos um), não todos.
NÃO CAIA NESSA!
A banca explora a confusão entre ALL/ANY e a contagem simples de atendimentos. Candidatos desavisados escolhem a alternativa D (que parece intuitiva) ou A (que usa a palavra ALL). O padrão correto é o da dupla negação (NOT EXISTS com NOT IN), típico de consultas de divisão.
PEGA ESSA DICA!
Para memorizar: “divisão relacional = para todo X, não existe X sem Y”. Decore a estrutura com NOT EXISTS (SELECT ... WHERE NOT IN (SELECT ...)). Sempre desconfie de consultas que usam ALL ou ANY diretamente, pois elas comparam linha a linha, não conjuntos.