Der Ungleich-Operator, geschrieben als <> oder !=, ist wahr, wenn zwei Werte verschieden sind. Setz ihn in eine WHERE-Klausel, um die Zeilen auszuschließen, die einem Wert entsprechen. Die Beispiele funktionieren in PostgreSQL, MySQL, SQLite und SQL Server.
So verwendest du Ungleich
Setz <> oder != zwischen zwei Werte. Beide bedeuten genau dasselbe. <> ist die Schreibweise des SQL-Standards, != die der meisten Programmiersprachen.
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 einer Abfrage steht Ungleich in der WHERE-Klausel und behält jede Zeile, deren Wert abweicht:
-- 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
Ticket 4 fehlt im Ergebnis, obwohl sein Status nicht 'closed' ist. Das ist die erste Regel unten.
Wichtige Regeln
-
Ungleich trifft nie auf NULL zu. Ein Vergleich mit NULL ergibt NULL (unbekannt) statt wahr, deshalb verwirft die
WHERE-Klausel die Zeile. FügeOR column IS NULLhinzu, um Zeilen ohne Wert zu behalten:
-- 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
-
Ein NULL in einer
NOT IN-Liste entfernt jede Zeile.status NOT IN ('closed', 'pending')ist die Kurzform vonstatus <> 'closed' AND status <> 'pending', also macht ein einziges NULL in der Liste die ganze Bedingung unbekannt. Pass darauf auf, wenn die Liste aus einer Unterabfrage auf einer Spalte kommt, die NULLs erlaubt:
-- 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 und SQL Server ignorieren standardmäßig Groß- und Kleinschreibung, dort ist
'Apple' <> 'apple'also falsch. -
Frag nach dem, was du willst, wenn du kannst.
status <> 'closed'trifft auch auf jeden Status zu, den später jemand hinzufügt, und weil es meist den Großteil der Tabelle trifft, hilft der Datenbank ein Index kaum. Wenn du „offen oder ausstehend“ meinst, sagtstatus IN ('open', 'pending')genau das.
Alternative Syntax
NOT (status = 'closed') ist eine andere Schreibweise für status <> 'closed' und überspringt NULLs auf dieselbe Weise.
Für einen Vergleich ohne NULL-Überraschung nimm IS DISTINCT FROM, ein NULL-sicheres Ungleich, das NULL als eigenen Wert behandelt (SQL Server hat es 2022 eingeführt, SQLite in 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');
Wann solltest du Ungleich verwenden?
Nutze Ungleich, wenn eine Abfrage die Zeilen mit einem bestimmten Wert überspringen soll. Die meisten Anwendungsfälle passen in eine dieser fünf Kategorien.
Einen Status oder eine Kategorie herausfiltern
Stornierte Bestellungen, ungültige Rechnungen, eine Kategorie, die du nicht führst: <> lässt die Zeilen mit diesem Wert weg und behält alles andere.
Einen bestimmten Datensatz überspringen
Vergleiche eine ID, um eine Zeile oder Gruppe auszulassen: den Artikel, den jemand gerade liest, wenn du verwandte auflistest, den angemeldeten User in einer Liste anderer Mitglieder oder eine Abteilung in einem Firmenbericht. Zahlen brauchen keine Anführungszeichen.
Ergebnisse mit weiteren Bedingungen eingrenzen
Kombiniere <> mit AND und OR, um einen Wert auszuschließen und gleichzeitig nach anderen Spalten zu filtern, etwa Bestellungen, die nicht storniert sind und über einem bestimmten Betrag liegen. Um mehrere Werte derselben Spalte auszuschließen, nimm NOT IN.
Zeilen finden, in denen sich zwei Spalten unterscheiden
Ungleich funktioniert auch zwischen zwei Spalten. Vergleiche einen alten Wert mit einem neuen, eine gezählte Menge mit dem erfassten Bestand oder eine Lieferadresse mit einer Rechnungsadresse.
Zeilen ohne Wert behalten
Da <> NULLs überspringt, entscheide, ob Zeilen ohne Wert ins Ergebnis gehören. Füge OR column IS NULL hinzu, um sie zu behalten, oder nutze die NULL-sichere Syntax von oben.
Praxisbeispiele für Ungleich
Die relevanten Rechnungen summieren
Ungültige Rechnungen sollen nicht zum Umsatz zählen:
-- 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
Verwandte Artikel auflisten, ohne den aktuellen
Ein Leser ist auf Artikel 2. Zeig die anderen Artikel zum selben Thema:
-- 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
Nur verkaufbare Produkte anzeigen
Lass eingestellte Produkte, Produkte ohne Preis und nicht vorrätige Produkte weg:
-- 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
Die tatsächlich geänderten Felder finden
Ein Audit-Log erfasst jedes Speichern, auch solches, das nichts geändert hat. Vergleiche die beiden Spalten, um nur echte Änderungen zu behalten:
-- 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
Wenn eine der Spalten NULL sein kann, nimm IS DISTINCT FROM (oder NOT (old_value <=> new_value) in MySQL), sonst zählt ein erstmals gesetzter Wert nicht als Änderung.
Alle erinnern, die noch nicht zugesagt haben
Gäste, die nicht geantwortet haben, haben ein NULL in rsvp – und brauchen die Erinnerung am meisten:
-- 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
Weiterführende Infos zu Ungleich
In diesem Blog:
- SQL-COALESCE-Guide: NULLs vor dem Vergleich durch einen Wert ersetzen
-
SQL-LIKE-Guide:
NOT LIKE, um Text auszuschließen, der einem Muster entspricht - SQL-CASE-Guide: Vergleiche nutzen, um einen Wert auszuwählen
- HAVING vs. WHERE in SQL: wohin ein Filter gehört, wenn du Zeilen gruppierst
- Zwei Werte in PostgreSQL vergleichen: die anderen Vergleichsoperatoren
Offizielle Dokumentation:
- PostgreSQL: Vergleichsoperatoren
- MySQL:
<>und!= - SQLite: Operatoren
-
SQL Server:
<>,!=und IS DISTINCT FROM
Beekeeper Studio ist eine kostenlose & quelloffene Datenbank-GUI
Das beste SQL-Abfrage- & Editor-Tool, das ich je benutzt habe. Es bietet alles, was ich zum Verwalten meiner Datenbank brauche. - ⭐⭐⭐⭐⭐ Mit
Beekeeper Studio ist schnell, intuitiv und einfach zu bedienen. Beekeeper unterstützt jede Menge Datenbanken und läuft hervorragend auf Windows, Mac und Linux.
Was User über Beekeeper Studio sagen
„Beekeeper Studio hat meinen alten SQL-Workflow komplett ersetzt. Es ist schnell, intuitiv und macht die Arbeit mit Datenbanken wieder zum Vergnügen.“
„Ich habe viele Datenbank-GUIs ausprobiert, aber Beekeeper trifft die perfekte Balance zwischen Funktionsumfang und Einfachheit. Es funktioniert einfach.“