Questão nº 36
Questão de Tecnologia da Informação · FGV CVM 2024 (nº 36)
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 a where a.idpaciente = p.id and 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)); (alternativa correta)
- Cselect p.nome from paciente p where exists ( select idmedico from atendimento where idpaciente = p.id);
- Dselect p.nome from paciente p, atendimento a where a.idpaciente=p.id group by p.nome having count() = (select count() from medico);
- Eselect p.nome from paciente p, atendimento a where a.idpaciente = p.id and a.idmedico = any (select id from medico);
Resposta comentada
Gabarito Alternativa B
O conceito-chave aqui é a divisão relacional, que busca entidades (como pacientes) que se relacionam com todas as instâncias de outra entidade (como médicos). Uma forma comum de resolver isso em SQL é usando a lógica de "não existe nenhum que não", ou seja, `NOT EXISTS` combinado com `NOT IN`.
(A) Incorreta: A condição `a.idmedico = all (select id from medico)` exige que o `idmedico` de um atendimento seja igual a todos os IDs de médicos simultaneamente, o que é logicamente impossível se houver mais de um médico.
(B) Correta: Esta query utiliza a lógica de dupla negação: "seleciona pacientes para os quais não existe um médico que não os tenha atendido". Isso significa que todos os médicos atenderam o paciente, resolvendo corretamente a divisão relacional.
(C) Incorreta: Esta query simplesmente verifica se o paciente teve algum atendimento, ou seja, se existe pelo menos um médico que o atendeu. Não garante que foi atendido por todos os médicos.
(D) Incorreta: Esta é a armadilha. A query conta o número total de atendimentos por paciente (`count()`). Para que funcionasse, seria necessário contar o número de médicos distintos que atenderam o paciente (`count(distinct a.idmedico)`). Como está, um paciente que foi atendido por um médico duas vezes e por outro médico uma vez (total de 3 atendimentos) seria excluído se houvesse apenas dois médicos no total.
(E) Incorreta: A condição `a.idmedico = any (select id from medico)` é sempre verdadeira para qualquer `idmedico` válido, pois um ID de médico sempre será igual a algum ID na tabela de médicos. Esta query retorna todos os pacientes que tiveram qualquer* atendimento.
Fonte: FGV CVM 2024 Analista CVM - TI Sistemas e Desenvolvimento (Perfil 8) (Caderno Tipo 1). Reproduzida para fins de estudo.