Considerando as tabelas A e B de um banco de dados relacional e que os campos id dessas tabelas referem-se às suas chaves primárias, julgue o item seguinte.
Se as tabelas A e B em questão tiverem, também, uma coluna denominada cod_grupo que admita valores NULL, então a consulta a seguir não retornará qualquer registro se houver, ao menos, um valor NULL na coluna cod_grupo da tabela B.
1
SELECT A.id
2
FROM table_A A
3
WHERE A.cod_grupo NOT IN (
4
SELECT B.cod_grupo FROM table_B B
5
)
CCerto
EErrado
Revelar gabarito e comentário▾
GabaritoC — Certo
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”.
Comportamento do operador NOT IN com valores NULL em SQL
Gabarito: CERTO. A consulta não retornará nenhum registro se houver ao menos um valor NULL na coluna cod_grupo da tabela B, porque o operador NOT IN com um subconjunto que contém NULL nunca avalia a condição como verdadeira — qualquer comparação com NULL resulta em UNKNOWN, e o WHERE só retorna linhas cuja condição seja TRUE. Esse é um comportamento clássico da lógica de três estados (TRUE, FALSE, UNKNOWN) do SQL, que trata a ausência de valor como um estado distinto, não como um valor comparável.
O SQL não usa a lógica booleana binária tradicional. Em vez de apenas TRUE e FALSE, ele trabalha com três estados: TRUE, FALSE e UNKNOWN. Esse terceiro estado surge exatamente quando uma expressão envolve NULL, pois NULL não é um valor — é a ausência de valor. Qualquer comparação do tipo x = NULL, x <> NULL ou x IN (NULL) não é verdadeira nem falsa; ela é UNKNOWN. O WHERE filtra as linhas que satisfazem a condição, ou seja, apenas aquelas em que a expressão é TRUE. Linhas cuja condição é FALSE ou UNKNOWN são descartadas.
O operador NOT IN é uma abreviação lógica para <> ALL. Ou seja, A.cod_grupo NOT IN (SELECT B.cod_grupo FROM table_B B) equivale a dizer: A.cod_grupo <> ALL (SELECT B.cod_grupo FROM table_B B). Para que essa condição seja TRUE, o valor de A.cod_grupo precisa ser diferente de todos os valores retornados pela subconsulta. Se a subconsulta retorna um conjunto que inclui NULL, a comparação A.cod_grupo <> NULL é avaliada como UNKNOWN. Como a condição exige que a comparação seja verdadeira para todos os elementos, e uma delas é UNKNOWN, o resultado final da expressão <> ALL é UNKNOWN (ou FALSE, dependendo da implementação, mas nunca TRUE). Portanto, nenhuma linha de A satisfaz o WHERE.
Vamos a um exemplo concreto. Suponha que a tabela A tenha as linhas com cod_grupo = 1, 2 e 3, e a tabela B tenha cod_grupo = 2 e NULL. A subconsulta retorna o conjunto {2, NULL}. Para a linha de A com cod_grupo = 1, a condição 1 NOT IN (2, NULL) é avaliada como: 1 <> 2 (TRUE) AND 1 <> NULL (UNKNOWN). Como TRUE AND UNKNOWN = UNKNOWN, a condição não é TRUE, e a linha é descartada. O mesmo ocorre para cod_grupo = 2 (2 <> 2 é FALSE, então a condição é FALSE) e para cod_grupo = 3 (3 <> 2 é TRUE, mas 3 <> NULL é UNKNOWN, então o resultado é UNKNOWN). Nenhuma linha é retornada.
A pegadinha aqui é que muitos candidatos pensam que o NOT IN simplesmente exclui os valores que estão na lista, ignorando o NULL. Mas o NULL não é um valor que possa ser comparado; ele contamina o resultado. A alternativa segura para evitar esse comportamento é usar NOT EXISTS com uma condição de junção explícita, que trata o NULL de forma mais previsível, ou filtrar os NULLs na subconsulta com WHERE B.cod_grupo IS NOT NULL.
NÃO CAIA NESSA!
A banca explora a confusão entre NOT IN e NOT EXISTS. Muitos alunos assumem que NOT IN apenas exclui os valores presentes na lista, ignorando o efeito do NULL. Mas o NULL não é um valor comparável: qualquer comparação com ele resulta em UNKNOWN, e o WHERE exige TRUE. Por isso, a presença de um único NULL na subconsulta faz o NOT IN retornar vazio. Para evitar essa armadilha, lembre-se: NOT IN com NULL na subconsulta = resultado vazio. Se a intenção é excluir apenas os valores não nulos, use NOT EXISTS ou filtre os NULLs.
1Subconsulta retorna NULL
2Comparação com NULL = UNKNOWN
3WHERE exige TRUE
4Nenhuma linha retornada
LEVEL · soulevel.com.br
Item — ✅ CERTO
A afirmação está correta. A consulta SELECT A.id FROM table_A A WHERE A.cod_grupo NOT IN (SELECT B.cod_grupo FROM table_B B) não retornará nenhum registro se houver ao menos um valor NULL na coluna cod_grupo da tabela B. Isso ocorre porque o operador NOT IN é equivalente a <> ALL, e a comparação A.cod_grupo <> NULL é sempre UNKNOWN. Como a condição do WHERE precisa ser TRUE para que a linha seja retornada, e a presença de NULL na subconsulta torna a expressão UNKNOWN (ou FALSE), nenhuma linha satisfaz a condição. Esse é um comportamento fundamental da lógica de três estados do SQL, que trata NULL como ausência de valor, não como um valor comparável.