L'operatore di disuguaglianza (not equal), scritto <> o !=, è vero quando due valori sono diversi. Usalo in una clausola WHERE per escludere le righe che corrispondono a un valore. Gli esempi funzionano in PostgreSQL, MySQL, SQLite e SQL Server.
Come usare il not equal
Metti <> o != tra due valori. Significano esattamente la stessa cosa. <> è la forma dello standard SQL, mentre != è quella usata dalla maggior parte dei linguaggi di programmazione.
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.
In una query, il not equal va nella clausola WHERE e mantiene tutte le righe con un valore diverso:
-- 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
Il ticket 4 non compare nel risultato, anche se il suo stato non è 'closed'. È la prima regola qui sotto.
Regole da conoscere
-
Il not equal non corrisponde mai a NULL. Confrontare NULL con qualsiasi cosa restituisce NULL (sconosciuto) anziché vero, quindi la clausola
WHEREscarta la riga. AggiungiOR column IS NULLper mantenere le righe senza valore:
-- 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
-
Un NULL in una lista
NOT INelimina tutte le righe.status NOT IN ('closed', 'pending')è un'abbreviazione distatus <> 'closed' AND status <> 'pending', quindi un solo NULL nella lista rende sconosciuta l'intera condizione. Fai attenzione quando la lista arriva da una subquery su una colonna che ammette NULL:
-- 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 ignorano maiuscole e minuscole per impostazione predefinita, quindi lì
'Apple' <> 'apple'è falso. -
Quando puoi, chiedi esattamente ciò che vuoi.
status <> 'closed'corrisponde anche a qualsiasi stato aggiunto in futuro e, dato che di solito corrisponde alla maggior parte della tabella, il database raramente trae vantaggio da un indice. Se intendi “aperto o in attesa”,status IN ('open', 'pending')lo dice chiaramente.
Sintassi alternativa
NOT (status = 'closed') è un altro modo di scrivere status <> 'closed' e salta i NULL allo stesso modo.
Per confrontare senza la sorpresa dei NULL, usa IS DISTINCT FROM, un not equal sicuro rispetto ai NULL che tratta NULL come un valore a sé (SQL Server lo ha aggiunto nel 2022, SQLite nella 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 usare il not equal?
Usa il not equal quando una query deve saltare le righe con un valore specifico. La maggior parte degli usi rientra in uno di questi cinque casi.
Escludere uno stato o una categoria
Ordini annullati, fatture stornate, una categoria che non tratti: <> esclude le righe con quel valore e mantiene tutto il resto.
Saltare un record specifico
Confronta un id per escludere una riga o un gruppo: l'articolo che qualcuno sta leggendo quando elenchi quelli correlati, l'utente connesso in una lista di altri membri o un reparto in un report aziendale. I numeri non hanno bisogno di virgolette.
Restringere i risultati con altre condizioni
Combina <> con AND e OR per escludere un valore mentre filtri su altre colonne, ad esempio ordini non annullati e sopra un certo importo. Per escludere più valori della stessa colonna, usa NOT IN.
Trovare righe in cui due colonne differiscono
Il not equal funziona anche tra due colonne. Confronta un vecchio valore con uno nuovo, una quantità contata con quella registrata o un indirizzo di spedizione con uno di fatturazione.
Mantenere le righe con valore mancante
Dato che <> salta i NULL, decidi se le righe senza valore devono stare nel risultato. Aggiungi OR column IS NULL per mantenerle, oppure usa la sintassi NULL-safe vista sopra.
Esempi reali di not equal
Sommare le fatture che contano
Le fatture stornate non devono contare nel fatturato:
-- 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
Elencare gli articoli correlati, tranne quello che si sta leggendo
Un lettore è sull'articolo 2. Mostra gli altri articoli sullo stesso argomento:
-- 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
Mostrare solo i prodotti vendibili
Escludi i prodotti fuori produzione, quelli senza prezzo e quelli esauriti:
-- 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
Trovare i campi davvero modificati
Un audit log registra ogni salvataggio, compresi quelli che non hanno cambiato nulla. Confronta le due colonne per mantenere solo le modifiche reali:
-- 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 una delle due colonne può essere NULL, usa IS DISTINCT FROM (o NOT (old_value <=> new_value) in MySQL), altrimenti un valore impostato per la prima volta non conterà come modifica.
Ricordarlo a chi non ha ancora detto sì
Gli invitati che non hanno risposto hanno rsvp NULL, e sono proprio loro ad aver più bisogno del promemoria:
-- 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
Approfondimenti sul not equal
Su questo blog:
- Guida a COALESCE in SQL: sostituisci i NULL con un valore prima di confrontare
-
Guida a LIKE in SQL:
NOT LIKEper escludere testo che corrisponde a un pattern - Guida all'istruzione CASE in SQL: usa i confronti per scegliere un valore
- Having vs Where in SQL: dove va un filtro quando raggruppi le righe
- Confrontare due valori in PostgreSQL: gli altri operatori di confronto
Documentazione ufficiale:
- PostgreSQL: operatori di confronto
- MySQL:
<>e!= - SQLite: operatori
-
SQL Server:
<>,!=e IS DISTINCT FROM
Beekeeper Studio è una GUI per database gratuita & open source
Il miglior strumento per query & editor SQL che abbia mai usato. Offre tutto ciò che mi serve per gestire il mio database. - ⭐⭐⭐⭐⭐ Mit
Beekeeper Studio è veloce, intuitivo e facile da usare. Beekeeper supporta tantissimi database e funziona alla grande su Windows, Mac e Linux.
Cosa dicono gli utenti di Beekeeper Studio
"Beekeeper Studio ha sostituito completamente il mio vecchio flusso di lavoro SQL. È veloce, intuitivo e rende di nuovo piacevole lavorare con i database."
"Ho provato molte GUI per database, ma Beekeeper trova l'equilibrio perfetto tra funzionalità e semplicità. Funziona e basta."