Imagina que tu tá mexendo no banco de dados da faculdade e precisa achar os estudantes que estão em cursos específicos. Tipo "Programação", "Matemática" e "Física". Claro, dá pra escrever uma query grandona cheia de condições assim:
SELECT *
FROM students
WHERE course = 'Programação'
OR course = 'Matemática'
OR course = 'Física';
Mas vamos ser sinceros. Escrever esse tipo de coisa é cansativo e fica feio demais. Ainda bem que existe o operador IN, que deixa a mesma query bem mais enxuta e economiza tempo:
SELECT *
FROM students
WHERE course IN ('Programação', 'Matemática', 'Física');
Parece mágica, né? Em vez de um monte de OR, a gente só fala pro SQL procurar os valores nessa lista. E se quiser checar que o valor não tá na lista, usa NOT IN — Procura tudo que não tá nessa lista.
Sintaxe do operador IN
Olha só a sintaxe geral do IN:
SELECT colunas
FROM tabela
WHERE coluna IN (valor1, valor2, valor3, ...);
Bora ver uns exemplos.
Exemplo 1: Estudantes que fazem vários cursos
Imagina que a gente tem a tabela students:
| id | name | course |
|---|---|---|
| 1 | Anna | Programação |
| 2 | Mello | Física |
| 3 | Kate | Matemática |
| 4 | Dan | Química |
| 5 | Olly | Biologia |
A gente quer achar todos os estudantes que fazem "Programação", "Matemática" ou "Física". Bora usar o IN:
SELECT name, course
FROM students
WHERE course IN ('Programação', 'Matemática', 'Física');
Resultado:
| name | course |
|---|---|
| Anna | Programação |
| Mello | Física |
| Kate | Matemática |
Viu só? O IN deixou tudo bem mais fácil. Não precisa escrever um monte de OR, só coloca a lista dos valores que tu quer.
Exemplo 2: Estudantes que não fazem certos cursos
Agora, digamos que tu quer achar estudantes que não fazem "Programação", "Matemática" e "Física". Pra isso, o NOT IN é perfeito:
SELECT name, course
FROM students
WHERE course NOT IN ('Programação', 'Matemática', 'Física');
Resultado:
| name | course |
|---|---|
| Dan | Química |
| Olly | Biologia |
Então, o NOT IN retorna todas as linhas onde o valor da coluna course não tá na lista que tu passou.
Usando IN e NOT IN com subqueries
Os operadores IN e NOT IN são muito úteis quando tu precisa comparar dados entre duas tabelas. Por exemplo, imagina que temos duas tabelas:
Tabela students:
| id | name | course_id |
|---|---|---|
| 1 | Anna | 101 |
| 2 | Mello | 102 |
| 3 | Kate | 103 |
| 4 | Dan | 104 |
Tabela courses:
| id | name |
|---|---|
| 101 | Programação |
| 102 | Física |
| 103 | Matemática |
| 105 | Química |
Imagina que a gente quer achar estudantes que estão matriculados em cursos que existem na tabela courses. Aqui entra o subquery com IN:
SELECT name
FROM students
WHERE course_id IN (
SELECT id
FROM courses
);
Essa query funciona assim: o subquery SELECT id FROM courses retorna a lista de todos os ids dos cursos. Depois o IN checa se o course_id tá nessa lista.
Resultado:
| name |
|---|
| Anna |
| Mello |
| Kate |
Por que o Dan ficou de fora? Porque o course_id dele (104) não existe na tabela courses.
Detalhes de como funciona com NULL
O operador IN tem um detalhe importante: se na lista de valores tiver um NULL, isso pode afetar o resultado da query. Olha só esse exemplo.
Tabela grades:
| student_id | course_id | grade |
|---|---|---|
| 1 | 101 | A |
| 2 | 102 | NULL |
| 3 | 103 | B |
A query que procura estudantes com nota em ('A', 'B', 'C') pode ser assim:
SELECT student_id
FROM grades
WHERE grade IN ('A', 'B', 'C');
Resultado:
| student_id |
|---|
| 1 |
| 3 |
A linha com NULL na coluna grade é ignorada, porque NULL não faz parte de nenhuma lista.
Agora imagina que tu usa o NOT IN. Tipo assim:
SELECT student_id
FROM grades
WHERE grade NOT IN ('A', 'B', 'C');
Tu espera ver a linha com student_id = 2, mas o resultado vai ser vazio! Por quê? Porque NULL comparado com qualquer valor da lista sempre dá resultado indefinido (UNKNOWN). Isso pode confundir, então quando usar NOT IN, fica ligado se tem coluna com NULL. O melhor é fazer uma checagem explícita de NULL:
SELECT student_id
FROM grades
WHERE grade NOT IN ('A', 'B', 'C')
OR grade IS NULL;
Resultado:
| student_id |
|---|
| 2 |
Dicas pra usar IN e NOT IN
Usa IN pra deixar seu SQL mais legível
Se tu precisa checar se uma coluna tá numa lista de valores, sempre prefere o IN em vez de um monte de OR.
Cuidado com NOT IN e NULL
Se tiver coluna com NULL nos dados, pode dar resultado estranho. Melhor tratar NULL de forma explícita quando usar NOT IN.
Usa índices pra acelerar subqueries
Se tu usa IN com subquery, garante que a coluna do subquery tá indexada, senão pode ficar lento demais.
Exemplo de um caso real
Imagina que tu trabalha num sistema de loja online. Tem as tabelas orders e users. Tu quer achar todos os usuários que nunca fizeram pedido.
Tabela users:
| id | name |
|---|---|
| 1 | Anna |
| 2 | Mello |
| 3 | Kate |
| 4 | Dan |
Tabela orders:
| id | user_id | total |
|---|---|---|
| 1 | 1 | 500 |
| 2 | 3 | 300 |
Vamos usar o NOT IN pra resolver:
SELECT name
FROM users
WHERE id NOT IN (
SELECT user_id
FROM orders
);
Resultado:
| name |
|---|
| Mello |
| Dan |
Essa query funciona assim: primeiro o subquery SELECT user_id FROM orders retorna os ids dos usuários que fizeram pedidos (1 e 3). Depois o NOT IN tira eles da lista, sobrando só quem nunca fez pedido (Mello e Dan).
GO TO FULL VERSION