O operador de diferente (not equal), escrito <> ou !=, é verdadeiro quando dois valores são diferentes. Use-o em uma cláusula WHERE para deixar de fora as linhas que correspondem a um valor. Os exemplos funcionam no PostgreSQL, MySQL, SQLite e SQL Server.
Como usar o diferente
Coloque <> ou != entre dois valores. Eles significam exatamente a mesma coisa. <> é a grafia do padrão SQL, e != é a que a maioria das linguagens de programação usa.
value1 <> value2
value1 != value2
SELECT 5 <> 3;
-- Output: true
SELECT 'apple' != 'apple';
-- Output: false
SELECT NULL <> 3;
-- Output: NULL
-- MySQL and SQLite show true and false as 1 and 0. SQL Server can't
-- select a comparison like this: use it in a WHERE clause there.
Em uma query, o diferente vai na cláusula WHERE e mantém todas as linhas cujo valor é diferente:
-- Input: tickets
-- id | subject | status
-- ---+-----------------------+--------
-- 1 | Login fails on Safari | open
-- 2 | Typo on pricing page | closed
-- 3 | Export times out | pending
-- 4 | Add a dark theme | NULL
SELECT id, subject, status
FROM tickets
WHERE status <> 'closed';
-- Output:
-- id | subject | status
-- ---+-----------------------+--------
-- 1 | Login fails on Safari | open
-- 3 | Export times out | pending
O ticket 4 não aparece no resultado, mesmo que seu status não seja 'closed'. Essa é a primeira regra abaixo.
Regras importantes
-
O diferente nunca corresponde a NULL. Comparar NULL com qualquer coisa resulta em NULL (desconhecido) em vez de verdadeiro, então a cláusula
WHEREdescarta a linha. AdicioneOR column IS NULLpara manter as linhas sem valor:
-- Input: the tickets table above
SELECT id, subject, status
FROM tickets
WHERE status <> 'closed' OR status IS NULL;
-- Output:
-- id | subject | status
-- ---+-----------------------+--------
-- 1 | Login fails on Safari | open
-- 3 | Export times out | pending
-- 4 | Add a dark theme | NULL
-
Um NULL em uma lista
NOT INremove todas as linhas.status NOT IN ('closed', 'pending')é um atalho parastatus <> 'closed' AND status <> 'pending', então um único NULL na lista torna toda a condição desconhecida. Fique atento a isso quando a lista vier de uma subquery em uma coluna que aceita NULLs:
-- Input: the tickets table above
SELECT id, status FROM tickets WHERE status NOT IN ('closed', 'pending');
-- Output:
-- id | status
-- ---+-------
-- 1 | open
SELECT id, status FROM tickets WHERE status NOT IN ('closed', NULL);
-- Output:
-- id | status
-- ---+-------
-- (0 rows)
-
MySQL e SQL Server ignoram maiúsculas e minúsculas por padrão, então neles
'Apple' <> 'apple'é falso. -
Peça o que você quer sempre que puder.
status <> 'closed'também corresponde a qualquer status que alguém adicione depois e, como geralmente corresponde à maior parte da tabela, o banco raramente consegue aproveitar um índice. Se você quer dizer “aberto ou pendente”,status IN ('open', 'pending')diz exatamente isso.
Sintaxe alternativa
NOT (status = 'closed') é outra forma de escrever status <> 'closed', e ignora NULLs da mesma maneira.
Para comparar sem a surpresa do NULL, use IS DISTINCT FROM, um diferente seguro para NULL que trata NULL como um valor próprio (o SQL Server o adicionou na versão 2022, o SQLite na 3.39):
-- Input: the tickets table above
SELECT id, status FROM tickets WHERE status IS DISTINCT FROM 'closed';
-- Output:
-- id | status
-- ---+--------
-- 1 | open
-- 3 | pending
-- 4 | NULL
-- MySQL has no IS DISTINCT FROM. Use its NULL-safe <=> instead:
SELECT id, status FROM tickets WHERE NOT (status <=> 'closed');
Quando usar o diferente?
Use o diferente quando uma query deve ignorar as linhas que têm um valor específico. A maioria dos usos se encaixa em um destes cinco casos.
Excluir um status ou categoria
Pedidos cancelados, faturas anuladas, uma categoria que você não tem em estoque: <> deixa de fora as linhas com esse valor e mantém todo o resto.
Ignorar um registro específico
Compare um id para deixar de fora uma linha ou grupo: o artigo que alguém está lendo quando você lista os relacionados, o usuário logado em uma lista de outros membros, ou um departamento em um relatório da empresa. Números não precisam de aspas.
Refinar resultados com outras condições
Combine <> com AND e OR para excluir um valor enquanto filtra por outras colunas, como pedidos que não foram cancelados e estão acima de um certo valor. Para excluir vários valores da mesma coluna, use NOT IN.
Encontrar linhas em que duas colunas diferem
O diferente também funciona entre duas colunas. Compare um valor antigo com um novo, uma quantidade contada com o número registrado, ou um endereço de entrega com um endereço de cobrança.
Manter linhas em que o valor está ausente
Como <> ignora NULLs, decida se as linhas sem valor devem entrar no resultado. Adicione OR column IS NULL para mantê-las, ou use a sintaxe segura para NULL acima.
Exemplos reais de diferente
Somar as faturas que contam
Faturas anuladas não devem contar na receita:
-- Input: invoices
-- invoice_id | customer | status | amount
-- -----------+------------+--------+--------
-- 1001 | Acme Corp | paid | 1200.00
-- 1002 | Birch & Co | void | 450.00
-- 1003 | Acme Corp | open | 300.00
-- 1004 | Cobalt Ltd | paid | 875.50
SELECT SUM(amount) AS invoiced
FROM invoices
WHERE status <> 'void';
-- Output: 2375.50
Listar artigos relacionados, exceto o que está sendo lido
Um leitor está no artigo 2. Mostre os outros artigos sobre o mesmo tema:
-- Input: articles
-- id | title | topic
-- ---+----------------------+-------
-- 1 | Indexing basics | SQL
-- 2 | Your first JOIN | SQL
-- 3 | Docker for beginners | DevOps
-- 4 | Window functions | SQL
SELECT id, title
FROM articles
WHERE topic = 'SQL'
AND id <> 2;
-- Output:
-- id | title
-- ---+-----------------
-- 1 | Indexing basics
-- 4 | Window functions
Mostrar só produtos que você pode vender
Deixe de fora produtos descontinuados, produtos sem preço definido e produtos sem estoque:
-- Input: products
-- product_name | category | price | stock_quantity
-- ---------------+--------------+-------+---------------
-- Desk Organizer | Office | 18.50 | 40
-- Fax Machine | Discontinued | 89.00 | 3
-- Gift Wrap | Seasonal | 0.00 | 120
-- Trail Backpack | Outdoors | 64.00 | 0
-- Water Bottle | Outdoors | 12.99 | 75
SELECT product_name, category, price
FROM products
WHERE category <> 'Discontinued'
AND price > 0
AND stock_quantity <> 0;
-- Output:
-- product_name | category | price
-- ---------------+----------+------
-- Desk Organizer | Office | 18.50
-- Water Bottle | Outdoors | 12.99
Encontrar os campos que realmente mudaram
Um log de auditoria registra cada salvamento, incluindo os que não mudaram nada. Compare as duas colunas para manter só as mudanças reais:
-- Input: audit_log
-- log_id | field_name | old_value | new_value
-- -------+------------+-------------+------------
-- 1 | email | dan@old.com | dan@new.com
-- 2 | city | Austin | Austin
-- 3 | plan | free | pro
SELECT log_id, field_name, old_value, new_value
FROM audit_log
WHERE old_value <> new_value;
-- Output:
-- log_id | field_name | old_value | new_value
-- -------+------------+-------------+------------
-- 1 | email | dan@old.com | dan@new.com
-- 3 | plan | free | pro
Se qualquer uma das colunas puder ser NULL, use IS DISTINCT FROM (ou NOT (old_value <=> new_value) no MySQL), senão um valor definido pela primeira vez não contará como mudança.
Lembrar todos que ainda não confirmaram
Convidados que não responderam têm rsvp NULL, e são eles que mais precisam do lembrete:
-- Input: invitations
-- guest | email | rsvp
-- ------------+------------------+------
-- Ines Moreau | ines@example.com | yes
-- Raj Patel | raj@example.com | no
-- Hana Sato | hana@example.com | NULL
-- Leo Grant | leo@example.com | maybe
SELECT guest, email, rsvp
FROM invitations
WHERE rsvp <> 'yes' OR rsvp IS NULL;
-- Output:
-- guest | email | rsvp
-- ----------+------------------+------
-- Raj Patel | raj@example.com | no
-- Hana Sato | hana@example.com | NULL
-- Leo Grant | leo@example.com | maybe
Leitura adicional sobre diferente
Neste blog:
- Guia de SQL COALESCE: substitua NULLs por um valor antes de comparar
-
Guia de SQL LIKE:
NOT LIKEpara deixar de fora textos que correspondem a um padrão - Guia da instrução SQL CASE: use comparações para escolher um valor
- Having vs Where em SQL: onde colocar um filtro ao agrupar linhas
- Comparando dois valores no PostgreSQL: os outros operadores de comparação
Documentação oficial:
- PostgreSQL: Operadores de comparação
- MySQL:
<>e!= - SQLite: Operadores
-
SQL Server:
<>,!=e IS DISTINCT FROM
Beekeeper Studio é um cliente de banco de dados gratuito e open source
A melhor ferramenta de consultas e edição de SQL que já usei. Tem tudo o que preciso para gerenciar meu banco de dados. - ⭐⭐⭐⭐⭐ Mit
O Beekeeper Studio é rápido, intuitivo e fácil de usar. Ele suporta vários bancos de dados e funciona muito bem no Windows, Mac e Linux.
O que os usuários dizem sobre o Beekeeper Studio
"O Beekeeper Studio substituiu completamente meu antigo fluxo de trabalho com SQL. É rápido, intuitivo e torna o trabalho com bancos de dados agradável de novo."
"Já testei muitas GUIs de banco de dados, mas o Beekeeper encontra o equilíbrio perfeito entre recursos e simplicidade. Simplesmente funciona."