SQL Comparações
Na aula WHERE, a Ana procurou valores iguais: os clientes do Piauí, o produto número 7. Mas muitas perguntas da loja não são de igualdade. "Quais produtos custam mais de R$ 100?" "Quais estão com o estoque abaixo de 20?" "Quais fornecedores não são do Brasil?" Para elas existem os operadores de comparação: os sinais =, <>, >, <, >= e <=, que você já conhece da matemática da escola.
- Os seis operadores de comparação e o que cada um pergunta.
- Que toda comparação tem uma resposta: 1 (verdadeiro) ou 0 (falso).
- A diferença entre
>e>=, que decide se o valor "da borda" entra ou não. - Que
<>e!=são a mesma coisa: "diferente". - Como comparar textos e datas, e por que
'Ana'e'ana'são diferentes. - As armadilhas dos números brasileiros (vírgula decimal e ponto de milhar) e os erros reais do SQLite.
A ideia: uma pergunta de sim ou não
Uma comparação é uma pergunta que só tem duas respostas: sim ou não. "5 é maior que 3?" Sim. "5 é menor que 3?" Não. O banco responde com números: 1 quer dizer "sim, é verdade" e 0 quer dizer "não, é falso". Você pode ver isso com um SELECT sem tabela, como a calculadora da aula SELECT:
SELECT 5 > 3, 5 < 3;
O WHERE usa exatamente isso. Para cada linha da tabela, ele faz a pergunta e olha a resposta: se deu 1, a linha entra no resultado; se deu 0, fica de fora.
Os seis operadores
| Operador | Pergunta | Exemplo na Loja Aurora |
|---|---|---|
= | É igual a? | estado = 'PI' |
<> ou != | É diferente de? | pais <> 'Brasil' |
> | É maior que? | preco > 100 |
< | É menor que? | estoque < 20 |
>= | É maior ou igual a? | preco >= 99 |
<= | É menor ou igual a? | estoque <= 20 |
Dica para não confundir > e <: a "boca" aberta do sinal fica sempre virada para o lado maior. Em preco > 100, a boca está virada para o preco: o preço é que tem de ser o maior.
1. Maior que e menor que
Quais produtos custam mais de R$ 100?
SELECT nome, preco FROM produtos WHERE preco > 100;
- WHERE
- "Onde": só as linhas que cumprirem a condição.
- preco
- A coluna testada em cada linha.
- >
- "É maior que". O sinal de maior.
- 100
- O valor de comparação. É número: sem aspas.
Quatro produtos, todos com preço acima de 100. E os produtos com pouco estoque, abaixo de 20 unidades? O sinal agora é o de menor:
SELECT nome, estoque FROM produtos WHERE estoque < 20;
Seis produtos, incluindo os dois que já acabaram (estoque 0): zero também é menor que 20.
2. "Ou igual": quem está na borda
O que acontece com um produto que tem exatamente 20 unidades? Com < 20, ele fica de fora: 20 não é menor que 20. Para incluí-lo, use <=, "menor ou igual":
SELECT nome, estoque FROM produtos WHERE estoque <= 20;
Agora são 7: entrou o Vaso de Cerâmica Médio, que tem 20 unidades. A mesma coisa acontece com o preço. O Teclado Compacto custa exatamente 99.0:
| Condição | O teclado (99.0) entra? | Linhas |
|---|---|---|
preco > 99 | Não: 99 não é maior que 99 | 4 |
preco >= 99 | Sim: 99 é igual a 99 | 5 |
SELECT nome, preco FROM produtos WHERE preco >= 99;
Na hora de escrever, pense na frase em português. "Mais de 100" é > 100. "A partir de 100", "100 ou mais", "no mínimo 100" é >= 100. "Até 20" é <= 20. "Menos de 20" é < 20.
Missão: a loja vai montar uma prateleira de "tudo abaixo de R$ 20". A consulta está com o sinal errado: mostra os produtos que custam mais de 20. Conserte para mostrar os que custam menos de 20.
SELECT nome, preco FROM produtos WHERE preco > 20;
SELECT nome, preco FROM produtos WHERE preco < 20;
3. Diferente: <> e !=
Quais fornecedores são de fora do Brasil? Os que têm o país diferente de 'Brasil':
SELECT nome, pais FROM fornecedores WHERE pais <> 'Brasil';
O sinal <> se lê "menor ou maior", ou seja, "diferente". É a forma do SQL padrão. O SQLite (e também o MySQL, o PostgreSQL e o SQL Server) aceita ainda o !=, que vem de outras linguagens de programação. Os dois fazem exatamente a mesma coisa:
SELECT nome, pais FROM fornecedores WHERE pais != 'Brasil';
Com números é igual. Todos os produtos que não são de papelaria (a categoria 1):
SELECT nome, preco FROM produtos WHERE categoria_id <> 1;
A loja tem 45 produtos e 6 são de papelaria, por isso vieram 39.
NULL
A Ana quis todos os clientes, menos o Tiago, e comparou o email:
SELECT nome, email FROM clientes WHERE email <> 'tiago.fontes@exemplo.com.br';
São 30 clientes, e ela esperava 29. Vieram 26. Os 3 clientes sem email (NULL) também sumiram. Um campo sem valor não é "igual" nem "diferente" de nada: a comparação com NULL não dá nem 1 nem 0, e o WHERE só deixa passar o 1. Esse comportamento tem aula própria: O Valor NULL.
4. Comparando textos
Igual e diferente: letra por letra
Como você viu em WHERE, dois textos só são iguais se forem idênticos, com as mesmas maiúsculas e os mesmos acentos:
SELECT 'Ana' = 'Ana', 'Ana' = 'ana';
O primeiro dá 1 (iguais); o segundo dá 0 (diferentes, por causa do A maiúsculo). É por isso que procurar 'mouse sem fio' não acha o produto Mouse Sem Fio.
Maior e menor: a ordem das letras
Com textos, "menor" quer dizer "vem antes na ordem". 'Ana' < 'Bruno' é verdade, porque A vem antes de B. Quais clientes têm o nome antes da letra C?
SELECT nome FROM clientes WHERE nome < 'C';
Vieram os nomes que começam com A e com B. Mas cuidado: a ordem que o SQLite usa não é a do dicionário. Ele compara o código de cada letra no computador, e nessa ordem todas as maiúsculas vêm antes de todas as minúsculas, e as letras acentuadas vêm depois de todas as outras:
SELECT 'Ana' < 'Bruno', 'Zé' < 'ana', 'Ébano' > 'Zé';
| Comparação | Resposta | Por quê |
|---|---|---|
'Ana' < 'Bruno' | 1 | A vem antes de B, como no dicionário |
'Zé' < 'ana' | 1 | Toda maiúscula (até o Z) vem antes de toda minúscula |
'Ébano' > 'Zé' | 1 | A letra acentuada É vem depois do Z |
Para comparar textos pelo começo, o mais comum é o LIKE (aula LIKE); para pôr textos em ordem, o ORDER BY (aula ORDER BY).
Se a comparação de textos liga ou não para maiúsculas depende da collation (as regras de comparação de textos) do banco:
- SQLite: por padrão, liga.
'Ana' = 'ana'dá 0. - MySQL: a collation padrão (
utf8mb4_0900_ai_ci) não liga: lá,'Ana' = 'ana'é verdade. Ocido nome quer dizer case-insensitive, "não diferencia maiúsculas". - SQL Server: depende da collation escolhida na instalação, que segue o idioma do sistema. Na de inglês dos Estados Unidos,
SQL_Latin1_General_CP1_CI_AS, oCItambém quer dizer "não diferencia maiúsculas".
Ou seja: a mesma consulta pode achar o cliente num banco e não achar no outro. Escreva o valor exatamente como está gravado e você não depende disso.
5. Comparando datas
As datas da Loja Aurora estão gravadas como texto no formato ano-mês-dia (2000-10-05). Esse formato tem uma vantagem: a ordem das letras é a mesma ordem do calendário. Então dá para comparar datas com > e <, desde que escritas no mesmo formato e entre aspas. Quais clientes nasceram a partir do ano 2000?
SELECT nome, nascimento FROM clientes WHERE nascimento >= '2000-01-01';
E os pedidos feitos em outubro de 2026 em diante?
SELECT id, data, frete FROM pedidos WHERE data >= '2026-10-01';
Os clientes sem data de nascimento (NULL) não aparecem em nenhuma das duas listas, pelo mesmo motivo do "diferente": comparar com NULL não dá 1. Mais sobre datas em Datas e Horas.
Missão: a loja quer mandar um presente aos clientes mais antigos, os que nasceram antes de 1975. Mostre o nome e a data de nascimento deles.
SELECT nome, nascimento FROM clientes;
SELECT nome, nascimento FROM clientes WHERE nascimento < '1975-01-01';
6. Número é número, texto é texto
Por que tanto cuidado em escrever números sem aspas? Porque, entre aspas, eles viram texto, e textos são comparados letra por letra:
SELECT 10 > 9, '10' > '9';
Como números, 10 é maior que 9 (deu 1). Como textos, '10' é menor que '9' (deu 0), porque o banco compara o primeiro caractere: '1' vem antes de '9', como "Ana" vem antes de "Bruno". Numa coluna de números, o SQLite muitas vezes converte o texto e acaba dando certo, mas não conte com isso: números sem aspas, sempre.
Formas diferentes de fazer a mesma coisa
Muitas condições podem ser escritas de mais de um jeito. As consultas abaixo dão os mesmos 7 produtos com estoque de até 20 unidades:
SELECT nome FROM produtos WHERE estoque <= 20;
SELECT nome FROM produtos WHERE estoque < 21;
SELECT nome FROM produtos WHERE 20 >= estoque;
A segunda só funciona porque o estoque é sempre um número inteiro: com preços, que têm centavos, < 21 deixaria passar um 20.50. A terceira inverte os lados, o que é correto, mas mais difícil de ler.
| Forma | Quando usar |
|---|---|
estoque <= 20 | Sempre: diz exatamente o que a frase diz ("até 20") |
estoque < 21 | Evite: depende de o valor ser inteiro |
20 >= estoque | Evite: coluna à esquerda é o costume |
pais <> 'Brasil' | O "diferente" do SQL padrão |
pais != 'Brasil' | Também funciona em todos os bancos grandes; escolha um e use sempre o mesmo |
Mais um jeito de dizer "não": o NOT, que inverte uma condição inteira (NOT preco > 100). É o assunto da aula NOT. E para uma faixa, como "entre 20 e 50", existe o BETWEEN (aula BETWEEN).
Quando dá errado
=> ou =<
Na escola, muita gente fala "igual ou maior", e o dedo escreve na ordem da fala:
SELECT nome FROM produtos WHERE preco => 100;
near ">": syntax error. O SQL não conhece o sinal =>: ele leu o = e depois encontrou um > sem sentido. Com =< é a mesma coisa (near "<": syntax error). Como consertar: o = vem sempre depois: >= e <=, como se fala "maior ou igual".
SELECT nome, pais FROM fornecedores WHERE pais ! = 'Brasil';
unrecognized token: "!", "símbolo não reconhecido". Sozinho, o ! não quer dizer nada no SQL; só o par !=, colado, é o "diferente". O mesmo vale para > =, < = e < >: os dois caracteres têm de estar juntos. Como consertar: pais != 'Brasil' ou pais <> 'Brasil'.
No Brasil, escrevemos R$ 99,90. No SQL, não:
SELECT nome, preco FROM produtos WHERE preco > 99,90;
near ",": syntax error. Para o SQL, a vírgula separa coisas (as colunas do SELECT, por exemplo), e não as casas decimais. Como consertar: use ponto: preco > 99.90.
Este é pior, porque não aparece mensagem nenhuma. A Ana quer os funcionários que ganham mais de três mil e duzentos reais, e escreveu como se escreve no Brasil:
SELECT nome, salario FROM funcionarios WHERE salario > 3.200;
Vieram todos os 8 funcionários. Para o SQL, o ponto é a casa decimal: 3.200 é "três vírgula dois", e todo mundo ganha mais do que R$ 3,20. Como consertar: números sem separador de milhar: salario > 3200. Aí vêm só os 4 que ganham mais de 3200.
SELECT nome, nascimento FROM clientes WHERE nascimento < '01/01/1980';
Nenhuma linha, sem erro. A comparação é de texto, letra por letra: '1985-03-12' começa com 1, e '01/01/1980' começa com 0. Nenhuma data gravada é "menor" que um texto que começa com zero. Como consertar: escreva a data como ela está gravada, ano-mês-dia: nascimento < '1980-01-01'.
Missão: a gerente quer ver os funcionários que ganham mais de R$ 3.200 por mês. A consulta não deu erro, mas trouxe todo mundo. Conserte.
SELECT nome, salario FROM funcionarios WHERE salario > 3.200;
SELECT nome, salario FROM funcionarios WHERE salario > 3200;
Referência rápida
| Operador | Nome | Exemplo | Na Loja Aurora |
|---|---|---|---|
= | igual | estado = 'PI' | 14 clientes |
<> | diferente (padrão) | pais <> 'Brasil' | 2 fornecedores |
!= | diferente | pais != 'Brasil' | 2 fornecedores |
> | maior que | preco > 100 | 4 produtos |
< | menor que | estoque < 20 | 6 produtos |
>= | maior ou igual | preco >= 99 | 5 produtos |
<= | menor ou igual | estoque <= 20 | 7 produtos |
| Sintoma | Causa provável |
|---|---|
near ">": syntax error ou near "<": syntax error | Sinal invertido: => ou =< |
unrecognized token: "!" | Espaço no meio do != |
near ",": syntax error | Vírgula decimal: use ponto |
| Vieram linhas demais, sem erro | Ponto de milhar: 3.200 é 3,2 |
| Nenhuma linha, sem erro | Texto com maiúsculas diferentes, data no formato errado, ou NULL |
Faltaram linhas num <> | As linhas com NULL naquela coluna nunca entram |
Exercícios
1. Mais de 50 reais
Complete o operador para mostrar os produtos que custam mais de 50:
2. No mínimo 100 unidades
Complete o operador para mostrar os produtos com estoque de 100 ou mais:
3. Qual é a resposta de SELECT 7 < 3;?
4. Qual destas condições mostra os clientes que não são de São Paulo?
5. O Teclado Compacto custa 99.0. Ele aparece em WHERE preco > 99?
6. A Ana escreveu WHERE salario > 5.000 querendo quem ganha mais de cinco mil. O que acontece?
Missão final: o frete grátis
Missão: na tabela pedidos, o frete grátis aparece como 0.0 na coluna frete. Mostre o id e o frete dos pedidos que pagaram frete, ou seja, com frete diferente de zero.
SELECT id, frete FROM pedidos WHERE frete = 0;
SELECT id, frete FROM pedidos WHERE frete <> 0;
São 79 pedidos com frete pago e 11 com frete grátis: 90 ao todo. A condição frete > 0 também resolve, porque nenhum frete é negativo.
Resumo
- Uma comparação é uma pergunta de sim ou não. O banco responde com 1 (verdadeiro) ou 0 (falso), e o
WHEREdeixa passar só as linhas que deram 1. - Os operadores:
=igual,<>ou!=diferente,>maior,<menor,>=maior ou igual,<=menor ou igual. >e<deixam a borda de fora;>=e<=incluem. O=vem sempre depois:>=, nunca=>.- Textos são comparados letra por letra, pelo código de cada letra: maiúsculas antes das minúsculas, acentuadas depois do Z. Em outros bancos, isso depende da collation.
- Datas no formato ano-mês-dia, entre aspas, podem ser comparadas com
>e<. - Números sem aspas, com ponto decimal e sem ponto de milhar:
3200,99.90. - Linhas com
NULLna coluna comparada nunca entram, nem num "diferente".