23rd Jun 2022 10 Leseminuten Verwendung von Vergleichsoperatoren mit NULL-Werten in SQL James Wondrasek NULL SQL-Operatoren Inhaltsverzeichnis SQL NULL - Das Bekannte Unbekannte Was ist ternäre Logik und wie funktioniert sie in SQL? SQL-Vergleichsoperationen und NULL-Werte Die anderen Vergleichsoperatoren von SQL NULL und der <-Operator NULL und der > Operator NULL und der <= Operator NULL und der >= Operator SQL-Vergleichsoperatoren, die mit NULLs arbeiten SQL NULL und Outer Joins Erfahren Sie mehr über SQL-NULLs Der SQL-NULL-Wert erfüllt einen besonderen Zweck. Er bringt auch kontraintuitive Verhaltensweisen mit sich, die SQL-Anfängern oder sogar erfahrenen Programmierern Schwierigkeiten bereiten können. Erfahren Sie, wie Sie diese Probleme bei der Verwendung von NULL mit Vergleichsoperatoren vermeiden können. Dieser Artikel wird Ihnen helfen, die besten Praktiken für die Erstellung von SQL-Abfragen zu beherrschen, die mit NULL-Werten arbeiten und Vergleichsoperatoren ( =, <>, <, > ) verwenden - und wenn Sie schon einmal eine SQL-Abfrage geschrieben haben, wissen Sie, dass das so ziemlich jede Abfrage ist, die Sie jemals schreiben werden! Dieses Wissen ist von grundlegender Bedeutung, und wenn Sie es beherrschen, wird SQL für Sie einfacher werden. Wir werden einen kurzen Überblick über SQL-NULLs geben, warum es sie gibt und wie sich ihre Seltsamkeiten auf die Abfrageergebnisse auswirken. Es folgen einige SQL-Abfragen, die diese Merkwürdigkeit demonstrieren. Dann werden wir Standardtechniken zum Schreiben von Abfragen besprechen, die korrekt mit NULLs und Vergleichsoperatoren umgehen. Zum Schluss gibt es noch eine kurze Zusammenfassung aller SQL-Vergleichsoperatoren und wie diese mit NULL interagieren. Aber keine Sorge. Es ist nicht so schwer, wie es klingt. Beginnen wir mit der Betrachtung von NULL-Werten in SQL. SQL NULL - Das Bekannte Unbekannte Datenbanken sind als eine einzige Quelle der Wahrheit gedacht. Was in den Feldern für jede Zeile aufgezeichnet wird, stellt das dar, was bekannt ist. Sehen Sie sich die folgende Tabelle an, die aus What Is a NULL in SQL (eine großartige Quelle für einen tiefen Einblick in SQL NULLs) übernommen wurde. Dies könnte ein Teil einer Datenbank sein, die von einem Simpsons-Superfan erstellt wurde. namesocial_sec_nostatusspouse Homer Simpson000-00-5000marriedMarjorie Bouvier Nedward Flanders000-00-4000marriedMaude Flanders Waylon Smithers000-00-8000singleNULL Dr Nick Riviera000-00-7000NULLNULL NULL steht hier für zwei verschiedene Dinge. Waylon Smithers ist bekanntermaßen ledig, so dass NULL in dieser Zeile in der Spalte Ehepartner einen nicht existierenden Wert darstellt. Aber wir wissen so wenig über Dr. Nick, dass die NULL-Werte in seinen Spalten Ehepartner und status einen unbekannten Wert darstellen. Um die Integrität einer Datenbank zu wahren, sind beide Interpretationen von NULL notwendig. Und um Programmierern zu helfen, diese Integrität trotz fehlender und unbekannter Werte aufrechtzuerhalten, integriert SQL NULLs in seine ternäre Logik. Was ist ternäre Logik und wie funktioniert sie in SQL? Die binäre Logik verwendet zwei Werte: Wahr und Falsch, 0 und 1, usw. Die ternäre Logik verwendet drei Werte. In SQL sind diese drei Werte Wahr, Falsch und Unbekannt. In der ternären Logik von SQL entspricht der Wert NULL dem Wert Unbekannt. Im Folgenden wird erläutert, wie die drei Werte der ternären Logik mit den logischen Operatoren von SQL NOT, OR und AND funktionieren: NOT TRUEFALSE FALSETRUE UNKNOWNUNKNOWN ORTRUEFALSEUNKNOWN TRUETRUETRUETRUE FALSETRUEFALSEUNKNOWN UNKNOWNTRUEUNKNOWNUNKNOWN ANDTRUEFALSEUNKNOWN TRUETRUEFALSEUNKNOWN FALSEFALSEFALSEFALSE UNKNOWNUNKNOWNFALSEUNKNOWN Das Wichtigste zum Schluss: Jede logische Operation mit NULL ergibt den Wert unknown , mit Ausnahme von TRUE OR NULL und FALSE AND NULL. Interessant, aber nichts, was Sie auswendig lernen müssen. Wie Sie sehen werden, hilft uns SQL, diese schwierige Logik zu umgehen. Das ist praktisch, denn die SQL-Vergleichsoperationen verwenden dieselbe ternäre Logik. SQL-Vergleichsoperationen und NULL-Werte Hier ist eine Abfrage, die Vergleiche und logische Operatoren verwendet. Raten Sie mal, wie viele Zeilen sie zurückgibt: SELECT spouse FROM simpsons WHERE spouse = NULL OR NOT (spouse = NULL) Beginnen wir mit der ersten Vergleichsoperation: WHERE spouse = NULL Was auch immer die Vergleichsspalte enthält - Gehälter, Tiernamen usw. -, wenn wir testen, dass sie gleich NULL ist, ist das Ergebnis unbekannt. Dies gilt selbst dann, wenn der Spaltenwert NULL ist. Dies verwirrt Programmierer, die mit anderen Sprachen vertraut sind. In Python zum Beispiel scheint der Wert None ähnlich wie SQL NULL zu sein und kann mit sich selbst verglichen werden: >>> None == None True Aber die erste Zeile der WHERE -Klausel wird unbekannt zurückgeben. Wenn unsere Abfrage ausgewertet wird, sieht sie also wie folgt aus: SELECT spouse FROM simpsons WHERE unknown OR NOT (spouse = NULL) Schauen wir uns die zweite Zeile der WHERE-Bedingung an: OR NOT (spouse = NULL) Dieser Vergleich wird ebenfalls unbekannt zurückgeben. Anhand der Wahrheitstabelle können wir sehen, dass NOT unknown unbekannt zurückgibt. Unsere Abfrage ist jetzt also eine: SELECT spouse FROM simpsons WHERE unknown OR unknown Die OR-Wahrheitstabelle oben sagt uns, dass das Ergebnis unbekannt sein wird. Eine WHERE-Klausel erfordert wahre Bedingungen. Dass das Ergebnis nicht falsch ist, reicht nicht aus. Obwohl die Abfrage so aussieht, als würde sie jede Zeile zurückgeben, führt die ternäre Logik von SQL und die Natur von SQL NULL dazu, dass null Zeilen zurückgegeben werden. Die anderen Vergleichsoperatoren von SQL Für diese Beispiele werden wir eine andere Tabelle verwenden, pet_owners: namepet_count Bob5 Cate2 AliceNULL Steve22 NULL und der <-Operator Verwenden wir die Tabellepet_owners , um zu sehen, wer weniger als 5 Haustiere hat. Das Ergebnis: name Cate Warum? Alice, die ihr Umfrageformular für Haustiere nicht ausgefüllt hat, hat NULL für ihre pet_count. Der Wert von NULL ist unbekannt. Ist NULL < 5? Das ist unbekannt, also kann Alice nicht in die Ergebnisse aufgenommen werden. NULL und der > Operator Jetzt werden wir sehen, wer mehr als 3 Haustiere hat. SELECT p.name FROM pet_owners p WHERE pet_count > 3 Das Ergebnis: name Bob Steve Warum? Wieder ist es der unbekannte Wert von NULL. Genauso wie es unbekannt ist, ob NULL 3 < 5, it is unknown if NULL >. Alice ist von den Ergebnissen ausgeschlossen.5,> NULL und der <= Operator In einer subtilen Änderung erhalten wir nun eine Liste aller Personen mit nicht mehr als 5 Haustieren. SELECT p.name FROM pet_owners p WHERE pet_count <= 5 Das Ergebnis: name Bob Cate Wenn wir unsere erste Abfrage von < auf <= ändern, wird Bob in die Ergebnismenge aufgenommen, Alice jedoch nicht. In der ersten Abfrage ist die Anzahl von Bobs Haustieren (5) nicht kleiner als 5. Aber sie ist kleiner oder gleich 5, so dass er jetzt im Abfrageergebnis enthalten ist. Alice taucht immer noch nicht auf. Wenn wir die Zeile von Alice untersuchen, können wir <= als Abkürzung für "NULL < 5 ODER NULL = 5" betrachten. Wir wissen von oben, dass "NULL < ANYTHING" ein unbekanntes Ergebnis liefert; von früher wissen wir, dass "NULL = ANYTHING" ebenfalls ein unbekanntes Ergebnis liefert. Auch hier wird Alice von den Ergebnissen ausgeschlossen. NULL und der >= Operator Nun wollen wir sehen, wer mindestens 3 Haustiere hat. SELECT p.name FROM pet_owners p WHERE pet_count >= 3 Das Ergebnis: name Bob Steve Wie <= können wir uns >= als eine logische Kombination zweier Vergleichsoperationen vorstellen. Für Alice ist der Vergleich also gleichbedeutend mit "NULL > 3 OR NULL = 3". Sie sollten sich jetzt darüber im Klaren sein, dass dies nur zu einem Wert von unknown führen kann. SQL-Vergleichsoperatoren, die mit NULLs arbeiten Um NULLs korrekt zu behandeln, bietet SQL zwei spezielle Vergleichsoperatoren: IS NULL und IS NOT NULL. Sie geben nur wahr oder falsch zurück und sind die beste Methode, um NULL-Werte in Ihre Abfragen einzubeziehen. Um das erwartete Ergebnis zu erhalten, können wir die Simpsons-Abfrage folgendermaßen umschreiben: SELECT spouse FROM simpsons WHERE spouse IS NULL OR spouse IS NOT NULL Jetzt gibt die Abfrage jede Zeile zurück, wie wir es erwartet haben. SQL NULL und Outer Joins Dies ist ein etwas fortgeschritteneres Thema. Wenn Sie neu bei SQL-JOINs sind, sollten Sie zuerst 7 SQL JOIN Beispiele mit detaillierten Erklärungen lesen. Es ist üblich, eine WHERE-Klausel zusammen mit dem Operator IS NOT NULL zu verwenden, um Zeilen mit NULL-Werten loszuwerden. Dies kann jedoch manchmal ein ineffizienter Weg sein, um ein Ergebnis zu erzielen. Hier ist der Grund dafür. Äußere Verknüpfungen - LEFT, RIGHT oder FULL JOIN - kann man sich wie eine INNER JOIN vorstellen (die übereinstimmende Zeilen zurückgibt) plus nicht übereinstimmende Zeilen, deren Spalten mit NULL-Werten gefüllt sind. Ein LEFT JOIN gibt alle Zeilen in der linken Tabelle des Joins mit den übereinstimmenden Zeilen aus der rechten Tabelle zurück (oder NULL-Werte, wenn es keine Übereinstimmung gibt). Eine RIGHT JOIN gibt alle Zeilen aus der rechten Tabelle mit den übereinstimmenden Zeilen (oder NULL-Werten) aus der linken Tabelle zurück. Eine FULL JOIN ist wie eine INNER JOIN, die auch alle nicht übereinstimmenden Zeilen der linken und rechten Tabelle, erweitert um NULLs, zurückgibt. Wenn die WHERE Klausel Ihrer Abfrage Zeilen herausfiltert, die durch NULLs erweitert wurden, heben Sie im Grunde Ihren Outer Join auf. Sie sollten Ihre Abfrage unter Verwendung einer INNER JOIN neu schreiben. In anderen Fällen interagieren NULLs mit Ihrer WHERE-Klausel und führen zu falschen Ergebnissen. Schauen wir uns ein Beispiel an, das dies verdeutlicht. Sie können es selbst ausführen, indem Sie dieses SQL-Fiddle verwenden (hier finden Sie einen Leitfaden mit weiteren Websites, die Sie für SQL-Übungen verwenden können). Für dieses Beispiel werden wir zwei Tabellen verwenden, eine für customers und eine für orders. idnameemail 1Alicealice@gmail.com 2Bobbob@hmail.com 3Catecate@imail.com Tabelle customers idorder_datecust_emailamount 12021-02-04bob@hmail.com50 22021-02-05cate@imail.com20 32021-02-06cate@imail.com40 42021-02-06bob@hmail.com15 Tabelle orders Wir möchten den Betrag sehen, den alle unsere registrierten Kunden seit dem 4. Februar 2021 ("2021-02-04") ausgegeben haben. Wir beginnen mit einem INNER JOIN. In dieser Abfrage gibt es einige zusätzliche SQL-Funktionen, die Ihnen vielleicht neu sind, aber LearnSQL hilft Ihnen dabei. Wir haben Artikel über COALESCE, Aggregatfunktionen wie SUM und die GROUP BY-Klausel. Sie brauchen sich jetzt nicht darum zu kümmern, was diese Funktionen tun. Konzentrieren Sie sich einfach darauf, was jede Abfrage zurückgibt, und beginnen Sie mit dieser Abfrage: SELECT c.name, COALESCE(SUM(o.amount),0) as 'Total' FROM customers c INNER JOIN orders o ON c.email = o.cust_email WHERE o.order_date > '2021-02-04' GROUP BY c.name; Die Abfrage gibt dieses Ergebnis aus: nameTotal Bob15 Cate60 Es sieht gut aus, aber wir haben 3 Kunden. Wenn wir jeden Kunden sehen wollen, müssen wir eine LEFT OUTER JOIN (kurz LEFT JOIN ) verwenden. Sie schließt jede Zeile in der linken Tabelle der FROM -Anweisung ein, auch wenn es keine passenden Daten in der rechten Tabelle gibt. So erhalten wir unsere nächste Abfrage: SELECT c.name, COALESCE(SUM(o.amount),0) as 'Total' FROM customers c LEFT JOIN orders o ON c.email = o.cust_email WHERE o.order_date > '2021-02-04' GROUP BY c.name; Die Ergebnisse könnten Sie überraschen: nameTotal Bob15 Cate60 Warum ist das so? Warum ist Alice immer noch nicht da? Eine einfachere Abfrage wird uns einen Hinweis geben: SELECT c.name, COALESCE(SUM(o.amount),0) as 'Total' FROM customers c LEFT JOIN orders o ON c.email = o.cust_email WHERE o.order_date > '2021-02-04' GROUP BY c.name; Das Ergebnis: nameorder_date Bob2021-02-04 Cate2021-02-05 Cate2021-02-06 Bob2021-02-06 Alice(null) Wie bereits erwähnt, enthält LEFT JOIN alle Zeilen aus der linken Tabelle. Wo es keine passende Zeile in der rechten Tabelle gibt, werden die Spalten mit NULLen gefüllt. Die WHERE-Klausel führt ihre Filterung nach JOIN durch, so dass alle Zeilen für Alice entfernt werden, da der Vergleich mit NULL, z. B. einer nicht existierenden order_date, ein unbekanntes Ergebnis liefert . WHERE gibt nur eine Zeile zurück, bei der die Bedingungen auf TRUE ausgewertet werden. Dies lässt sich beheben, indem man den bedingten Ausdruck, hier o.order_date > '2021-02-04', in die JOIN verschiebt, indem man ihn in die Klausel ON einfügt: SELECT c.name, COALESCE(SUM(o.amount),0) as 'Total' FROM customers c LEFT JOIN orders o ON c.email = o.cust_email WHERE o.order_date > '2021-02-04' GROUP BY c.name; Da wir eine LEFT JOIN verwenden, bleibt Alice trotz der zusätzlichen Datumsbedingung in der Ergebnismenge. Ihre NULL wird durch die Funktion COALESCE() in eine saubere "0" umgewandelt. Das Abfrageergebnis ist nun das, was wir erwartet haben: nameTotal Alice0 Bob15 Cate60 Erfahren Sie mehr über SQL-NULLs Sie sollten nun verstehen, wie SQL NULL-Werte behandelt und wie man am besten mit ihnen arbeitet. Sie kennen die Operatoren IS NULL und IS NOT NULL und wissen, dass die ternäre Logik von SQL immer Unbekannt zurückgibt, wenn etwas mit einem NULL-Wert verglichen wird , mit Ausnahme von zwei Sonderfällen. Sie haben auch gesehen, wie Sie Abfragen umschreiben können, damit Sie diese lästigen NULLs nicht herausfiltern müssen. Aber es gibt noch mehr über die Arbeit mit NULLs in SQL zu wissen. Ich schlage vor, dass Sie mit den Artikeln Wie ORDER BY und NULL in SQL zusammenarbeiten und NULL-Werte und die GROUP BY-Klausel weiter lernen. Und wenn Sie SQL wirklich beherrschen wollen, empfehle ich Ihnen den SQL-Übungssatz oder den SQL-Praxis Kurs. Sie bieten eine gründliche und leicht nachvollziehbare Lernerfahrung, die Ihnen helfen wird, Ihr Handwerk zu verfeinern. Tags: NULL SQL-Operatoren