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.

Você vai aprender
  • 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

OperadorPerguntaExemplo 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çãoO teclado (99.0) entra?Linhas
preco > 99Não: 99 não é maior que 994
preco >= 99Sim: 99 é igual a 995
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.

O "diferente" e o 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çãoRespostaPor quê
'Ana' < 'Bruno'1A vem antes de B, como no dicionário
'Zé' < 'ana'1Toda maiúscula (até o Z) vem antes de toda minúscula
'Ébano' > 'Zé'1A 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).

Nos outros bancos

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. O ci do 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, o CI també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.

FormaQuando usar
estoque <= 20Sempre: diz exatamente o que a frase diz ("até 20")
estoque < 21Evite: depende de o valor ser inteiro
20 >= estoqueEvite: 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

Sinal escrito ao contrário: => 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".

Espaço no meio do sinal
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'.

Vírgula no lugar do ponto decimal

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.

Ponto de milhar: o erro que não dá erro

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.

Data no formato brasileiro
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

OperadorNomeExemploNa Loja Aurora
=igualestado = 'PI'14 clientes
<>diferente (padrão)pais <> 'Brasil'2 fornecedores
!=diferentepais != 'Brasil'2 fornecedores
>maior quepreco > 1004 produtos
<menor queestoque < 206 produtos
>=maior ou igualpreco >= 995 produtos
<=menor ou igualestoque <= 207 produtos
SintomaCausa provável
near ">": syntax error ou near "<": syntax errorSinal invertido: => ou =<
unrecognized token: "!"Espaço no meio do !=
near ",": syntax errorVírgula decimal: use ponto
Vieram linhas demais, sem erroPonto de milhar: 3.200 é 3,2
Nenhuma linha, sem erroTexto 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:

SELECT nome, preco FROM produtos WHERE preco 50;

2. No mínimo 100 unidades

Complete o operador para mostrar os produtos com estoque de 100 ou mais:

SELECT nome, estoque FROM produtos WHERE estoque 100;

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 WHERE deixa 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 NULL na coluna comparada nunca entram, nem num "diferente".