Questão de Banco de Dados — Consultas e Comandos em SQL — Quadrix 2025
Banco de Dados›Consultas e Comandos em SQL
Código
qa699047
Banca
Quadrix
Órgão
CRM ES
Ano
2025
Cargo
ATI ( )
Situação hipotética para a questão.
No banco de dados do Conselho Regional de Medicina (CRM) de certo estado da federação, há as tabelas Medico, Especialidade, Medico_Especialidade e Pagamento. Essas tabelas estão descritas conforme os quadros a seguir.
Tabela Medico
id_medico
INT (PK)
nome
VARCHAR (100)
cpf
VARCHAR (11)
situacao
INT
numero_registro
VARCHAR(20)
data_registro
DATE
Tabela Especialidade
id_especialidade
INT
nome
VARCHAR (50)
codigo_cfm
VARCHAR (30)
Tabela Medico_Especialidade
id_medico_esp
INT (PK)
id_medico
INT (FK)
id_especialidade
INT (FK)
registro_especial
VARCHAR (20)
Tabela Pagamento
id_pagamento
INT (PK)
id_medico
INT (FK)
data_vencimento
DATE
data_pagamento
DATE
valor
DECIMAL (10, 2)
status
VARCHAR (20)
tipo
VARCHAR (30)
Na tabela Medico, o atributo situacao será do tipo inteiro e o número 0 corresponderá à situação em que o registro está “inativo”, 1, à situação em que o registro está “ativo”, e 2, à situação em que o registro está “suspenso”. Na tabela Especialidade, o atributo codigo_cfm corresponde ao código da especialidade no Conselho Federal de Medicina. Na tabela Medico_Especialidade, o atributo registro_especial corresponde ao número do registro de qualificação de especialista. Na tabela Pagamento, o atributo status pode receber os valores “pago”, “pendente” e “atrasado”, e o atributo tipo pode receber os valores “anuidade”, “multa” e “taxa de registro”.
Ainda com base na situação hipotética anterior e considerando que um analista tenha recebido a demanda de listar todos os médicos com registro ativo que sejam especialistas em mais de uma área. O analista, então, escreveu a seguinte query.
1| SELECT m.id_medico, m.nome
2| FROM Medico m
3| JOIN Medico_Especialidade me ON m.id_medico = me.id_medico
4| WHERE m.situacao = 1
5| GROUP BY m.id_medico, m.nome
6| HAVING COUNT(DISTINCT me.id_medico_esp) > 1;
Com base nessa situação hipotética e considerando‑se que a query escrita pelo analista tenha uma lista que não corresponde ao que foi demandado, assinale a opção que apresenta a mudança que deve ser feita na query, para que ela retorne corretamente o que foi demandado ao analista.
ANa linha 4, é necessário que se substitua o comando WHERE m.situacao = 1 por HAVING m.situacao = 1.
BNa linha 1, é necessário que se acrescente DISTINCT na cláusula SELECT.
CNa linha 6, é necessário que se utilize o comando COUNT(*) no lugar do comando COUNT(DISTINCT me.id_medico_ esp).
DNa linha 3, é necessário que se substitua JOIN por LEFT JOIN com a tabela Medico_Especialidade.
ENa linha 6, é necessário que se substitua o comando COUNT(DISTINCT me.id_medico_esp) por COUNT(DISTINCT me.id_especialidade).
Revelar gabarito e comentário▾
GabaritoE — Na linha 6, é necessário que se substitua o comando COUNT(DISTINCT me.id_medico_esp) por COUNT(DISTINCT me.id_especialidade).
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”.
Consultas SQL: GROUP BY, HAVING e COUNT(DISTINCT)
Gabarito: letra E. A query original conta quantos registros existem na tabela associativa Medico_Especialidade para cada médico, mas o correto é contar quantas especialidades distintas cada médico possui. Como a tabela Medico_Especialidade tem uma chave primária própria (id_medico_esp), cada linha representa um vínculo médico-especialidade, e COUNT(DISTINCT me.id_medico_esp) conta o número de linhas, não o número de especialidades diferentes. A correção é trocar para COUNT(DISTINCT me.id_especialidade), que conta as especialidades distintas.
O problema central está na distinção entre contar linhas e contar valores distintos de uma coluna. A tabela Medico_Especialidade é uma tabela associativa (ou de junção) que liga médicos a especialidades. Cada linha dessa tabela representa um vínculo entre um médico e uma especialidade. A coluna id_medico_esp é a chave primária dessa tabela, ou seja, é única para cada linha. Portanto, COUNT(DISTINCT me.id_medico_esp) conta o número de linhas da tabela associativa para cada médico, o que é equivalente a COUNT(*).
A demanda é listar médicos que sejam especialistas em mais de uma área. Isso significa que o médico deve ter vínculos com duas ou mais especialidades diferentes. Para contar corretamente, precisamos contar quantas especialidades distintas cada médico possui. A coluna id_especialidade na tabela associativa é a chave estrangeira que referencia a tabela Especialidade. Portanto, COUNT(DISTINCT me.id_especialidade) conta exatamente o número de especialidades distintas para cada médico.
Vamos analisar a query original linha por linha:
SELECT m.id_medico, m.nome — seleciona o id e o nome do médico.
FROM Medico m — define a tabela principal com alias m.
JOIN Medico_Especialidade me ON m.id_medico = me.id_medico — faz a junção entre as tabelas Medico e Medico_Especialidade pela chave estrangeira id_medico.
WHERE m.situacao = 1 — filtra apenas médicos com situação ativa (1).
GROUP BY m.id_medico, m.nome — agrupa os resultados por médico.
HAVING COUNT(DISTINCT me.id_medico_esp) > 1 — filtra os grupos que tenham mais de um registro na tabela associativa.
O erro está na linha 6. Como id_medico_esp é a chave primária da tabela associativa, cada valor é único. Portanto, COUNT(DISTINCT me.id_medico_esp) é igual a COUNT(*), que conta o número de linhas. Isso significa que a query retorna médicos que têm mais de um vínculo na tabela associativa, mas não necessariamente mais de uma especialidade distinta. Por exemplo, se um médico tiver dois registros na tabela associativa para a mesma especialidade (o que seria uma inconsistência, mas possível se não houver uma restrição de unicidade), a query o retornaria, mesmo que ele seja especialista em apenas uma área.
A correção correta é usar COUNT(DISTINCT me.id_especialidade), que conta o número de especialidades distintas. Isso garante que o médico seja especialista em mais de uma área, conforme a demanda.
Agora, vamos analisar cada alternativa:
Alternativa A — ❌ Incorreta
Substituir WHERE m.situacao = 1 por HAVING m.situacao = 1 está errado. A cláusula WHERE filtra linhas antes do agrupamento, enquanto HAVING filtra grupos após o agrupamento. Como m.situacao é uma coluna da tabela Medico, que não é agregada, ela deve ser filtrada na cláusula WHERE. Se colocada no HAVING, a query tentaria filtrar grupos por uma coluna que não está no GROUP BY nem é uma função agregada, o que causaria um erro na maioria dos SGBDs. Além disso, a demanda exige filtrar médicos ativos, o que é feito corretamente no WHERE.
Alternativa B — ❌ Incorreta
Acrescentar DISTINCT na cláusula SELECT não resolve o problema. O SELECT DISTINCT elimina linhas duplicadas no resultado final, mas como a query já agrupa por m.id_medico, m.nome, cada médico aparece apenas uma vez. Portanto, adicionar DISTINCT não altera o resultado e não corrige a contagem de especialidades.
Alternativa C — ❌ Incorreta
Substituir COUNT(DISTINCT me.id_medico_esp) por COUNT(*) não resolve o problema. Como id_medico_esp é a chave primária da tabela associativa, COUNT(DISTINCT me.id_medico_esp) é equivalente a COUNT(*). Ambos contam o número de linhas, não o número de especialidades distintas. Portanto, essa mudança não altera o resultado e continua retornando médicos com mais de um vínculo, não necessariamente mais de uma especialidade.
Alternativa D — ❌ Incorreta
Substituir JOIN por LEFT JOIN com a tabela Medico_Especialidade não resolve o problema. O LEFT JOIN incluiria médicos que não têm nenhum vínculo na tabela associativa, com valores NULL para as colunas de Medico_Especialidade. No entanto, como a cláusula WHERE m.situacao = 1 filtra médicos ativos, e o HAVING COUNT(DISTINCT me.id_medico_esp) > 1 exige mais de um vínculo, médicos sem vínculo seriam excluídos. Além disso, o LEFT JOIN não altera a contagem de especialidades distintas, que é o problema central.
Alternativa E — ✅ Correta ⟵ GABARITO
Substituir COUNT(DISTINCT me.id_medico_esp) por COUNT(DISTINCT me.id_especialidade) corrige o problema. A coluna id_especialidade na tabela associativa representa a especialidade do vínculo. Contar valores distintos dessa coluna conta exatamente o número de especialidades diferentes que cada médico possui. Assim, a query retorna apenas médicos que são especialistas em mais de uma área, conforme a demanda.
PEGA ESSA DICA!
Em consultas com tabelas associativas, preste atenção ao que você está contando. Se a tabela tem uma chave primária própria, COUNT(*) ou COUNT(chave_primaria) conta o número de vínculos. Para contar entidades distintas (como especialidades), use COUNT(DISTINCT coluna_estrangeira). Essa distinção é clássica em questões de SQL.