8th Jul 2024 10 Leseminuten Der SQL EXISTS-Operator Ignacio L. Bisso SQL-Operatoren Inhaltsverzeichnis Syntax des EXISTS-Operators Beispiel Datenbank: Luxusboote und Autos Beispiele für den SQL EXISTS-Operator Beispiel 1: Suche nach verkauften Produkten Beispiel 2: Verwendung des NOT EXISTS-Operators Beispiel 3: Verwendung von EXISTS mit NOT EXISTS Üben des EXISTS-Operators Übung 1: Alte Befehle Übung 2: Käufer von Bootsmotoren Übung 3: Nie gekauft Erweitern Sie Ihre SQL EXISTS-Operator-Kenntnisse Die Verwendung der SQL EXISTS-Klausel können wir komplexe Abfragen auf einfache Weise erstellen. Lernen Sie in diesem Artikel die Vor- und Nachteile des EXISTS-Operators in diesem Artikel. In SQL hilft der EXISTS Operator bei der Erstellung logischer Bedingungen in unseren Abfragen. Im Wesentlichen prüft er, ob Zeilen in einer Unterabfrage vorhanden sind. Wir zeigen Ihnen die Syntax von EXISTS, geben Ihnen einige Beispiele für die Verwendung und geben Ihnen dann einige Übungen zum Üben an die Hand. Wenn Sie gerade erst mit SQL anfangen oder eine SQL-Auffrischung brauchen, empfehle ich Ihnen den Kurs SQL für Anfänger. Er umfasst SQL-Themen, die von grundlegenden SELECTs bis hin zu komplexen Themen wie Joins, Aggregationen und Unterabfragen reichen. Es ist eine gute Möglichkeit, Ihre SQL-Kenntnisse aufzubauen, aufzufrischen oder zu erweitern. Syntax des EXISTS-Operators Sie sind wahrscheinlich mit SQL-Operatoren wie =, >, < und LIKE vertraut. Alle diese Operatoren können verwendet werden, um logische Bedingungen zu erstellen, die TRUE oder FALSE zurückgeben. Beispiele für übliche Bedingungen sind: WHERE Employee_id = 10345 WHERE Price < 1000 WHERE Name LIKE ‘John%’ Die Operatoren =, < und LIKE vergleichen zwei Elemente oder Operanden. Aus diesem Grund werden sie auch als binäre Operatoren bezeichnet. WHERE EXISTS ( subquery ) Schauen wir uns nun die gesamte SQL-Abfrage an, um festzustellen, wo die Bedingung EXISTS platziert werden kann: SELECT columns FROM table1 WHERE EXISTS (SELECT columns FROM table2); Der EXISTS Operator wird verwendet, um boolesche Bedingungen zu erstellen, um zu überprüfen, ob eine Unterabfrage Zeilen oder eine leere Menge zurückgibt. EXISTS gibt TRUE zurück, wenn seine Unterabfrage mindestens eine Zeile zurückgibt. Es spielt keine Rolle, wie viele Zeilen zurückgegeben werden oder wie viele Spalten sich in der Liste der Unterabfrage SELECT befinden. Nur wenn die Unterabfrage 0 Zeilen zurückgibt, gibt EXISTS FALSE zurück. Es ist wichtig zu beachten, dass keine der von der Unterabfrage zurückgegebenen Zeilen im Endergebnis angezeigt wird. Beispiel Datenbank: Luxusboote und Autos Schauen wir uns einige Beispielabfragen an, die auf einer Beispieldatenbank eines Unternehmens basieren, das Luxusautos und -boote verkauft. Das Unternehmen führt eine Übersicht über die Autos und Boote in der Tabelle product, die die Spalten product_id, product_name, product_price, product_type enthält. product_idproduct_nameproduct_priceproduct_type 100Ferrari F203000000Car 101Lamborghini AX3600000Car 102Pagani Zonda4300000Car 200VanDutch 582100000Boat 201Lamborghini B93400000Boat 202VanDutch 561800000Boat 300Boat Engine Yamei 1001000000Boat Die Datenbank hat auch eine Client Tabelle mit den Spalten client_id, client_name und country. client_idclient_namecountry 10John F.United States 11Samid A,Kuwait 12Majal H.Brunei 13Pierre B.France 14Abdul E.Kuwait Schließlich gibt es noch die sale mit den Spalten product_id, client_id, sale_date. (Der Einfachheit halber lasse ich die Idee einer Tabelle für Bestellungen weg; in dieser Art von Unternehmen kauft ein Kunde normalerweise nur ein Produkt auf einmal). client_idproduct_idcountry 102002020-03-05 101012024-04-05 112022023-03-05 121022021-03-07 121002023-03-05 122022024-04-09 133002022-03-05 103002020-07-19 133002023-11-25 Beispiele für den SQL EXISTS-Operator Beispiel 1: Suche nach verkauften Produkten Angenommen, der Marketingleiter möchte wissen, welche Autos und Boote zwischen dem 1. und 15. April 2024 verkauft wurden. Die folgende Abfrage erfüllt diesen Zweck: SELECT product_name FROM product p1 WHERE EXISTS ( SELECT * FROM sale s WHERE s.product_id = p1.product_id AND s.sale_date >= ‘2024-04-01’ AND s.sale_date <= ‘2024-04-15’ ) Ergebnisse: Product_name Lamborghini AX VanDutch 56 Es gibt andere Möglichkeiten, diese Abfrage zu schreiben, ohne den Operator EXISTS zu verwenden. Um jedoch zu erklären, wie der EXISTS Operator funktioniert, ist dies ein gutes Einstiegsbeispiel. Die Hauptabfrage SELECT ist sehr einfach; sie geht in die Tabelle product um die Spalte product_name zu erhalten. Wir wollen jedoch nicht alle product_names in der Tabelle haben. Wir wollen nur die Produkte, die TRUE für die folgende Bedingung liefern: WHERE EXISTS ( SELECT * FROM sale s WHERE s.product_id = p1.product_id AND s.sale_date >= ‘2024-04-01’ AND s.sale_date <= ‘2024-04-15’ ) Wenn wir die Bedingung analysieren, gibt die Subquery alle Verkaufsdatensätze für ein bestimmtes Produkt (p1.product_id) und für einen bestimmten Zeitraum (2024-04-01 bis 2024-04-15) zurück. Wenn die Unterabfrage Datensätze zurückgibt, dann gibt EXISTS TRUE zurück. Wenn die Unterabfrage keine Datensätze liefert, dann gibt EXISTS FALSE zurück. Beachten Sie, dass die Unterabfrage viele Male ausgeführt wird - einmal für jede Zeile, die von der externen Abfrage gelesen wird. Diese Art von Unterabfragen, die für jede in der Hauptabfrage verarbeitete Zeile einmal ausgeführt werden, nennt man "korrelierte Unterabfragen", und sie haben ihre Besonderheiten. Wenn Sie sich eingehender mit diesem Thema befassen möchten, empfehle ich Ihnen den Artikel Correlated Subquery in SQL: A Beginner's Guide. Beispiel 2: Verwendung des NOT EXISTS-Operators Nehmen wir an, der Manager möchte die Namen der Fahrzeuge wissen, die im gleichen Zeitraum nicht verkauft wurden. Diese Art von Abfrage - bei der nach Datensätzen gesucht wird, die nicht in der Datenbank vorhanden sind - eignet sich hervorragend für den Operator NOT EXISTS. Schließlich suchen wir nach Elementen, die nicht in der Datenbank vorhanden sind. Die Abfrage lautet wie folgt: SELECT * FROM product p1 WHERE p1.product_type = ‘Car’ AND NOT EXISTS ( SELECT * FROM sale s WHERE s.product_id = p1.product_id AND s.sale_date >= ‘2024-04-01’ AND s.sale_date <= ‘2024-04-15’ ) Ergebnisse: Product_idProduct_nameProduct_priceProduct_type 100Ferrari F203000000Car 102Pagani Zonda4300000Car Wenn wir einmal verstanden haben, wie der EXISTS Operator in SQL funktioniert, ist das Verständnis von NOT EXISTS sehr einfach; es ist das Gegenteil. Wenn EXISTS TRUE zurückgibt, dann gibt NOT EXISTS FALSE zurück und andersherum. In diesem Beispiel hat die Hauptabfrage eine WHERE Klausel mit zwei Bedingungen. Die erste Bedingung besteht darin, nach Produkten des Typs "Fahrzeug" zu suchen. Die zweite Bedingung verwendet NOT EXISTS, um nur die Produkte zu behalten, die im Zeitraum vom 2024-04-01 bis 2024-04-15 keine Verkäufe hatten. Mit anderen Worten, wir suchen nach Produkten, für die die Unterabfrage eine leere Ergebnismenge liefert - d. h. für die es in diesem Zeitraum keine Verkäufe gibt. In einigen Fällen können wir diese Art von Abfrage mit NOT IN und einer Unterabfrage lösen. In dieser speziellen Abfrage können wir diese WHERE Klausel einfügen: WHERE p1.product_type = ‘Car’ AND p1.product_id NOT IN (SELECT s.product_id FROM sale s WHERE s.sale_date >= ‘2024-04-01’ AND s.sale_date <= ‘2024-04-15’ ) Es gibt jedoch einen Unterschied in der Art und Weise, wie die Abfrage intern in der Datenbank ausgeführt wird. Die Bedingung der Unterabfrage NOT IN wird einmal ausgeführt, während die Bedingung der Unterabfrage NOT EXISTS für jede Zeile einmal ausgeführt wird. Das ist richtig; NOT EXISTS ist eine korrelierte Subquery. Lesen Sie die Artikel 5 SQL Subquery Examples und SQL IN Operator, um mehr über diese Operatoren zu erfahren. Beispiel 3: Verwendung von EXISTS mit NOT EXISTS Als Nächstes benötigen wir eine Liste der Kunden, die im Sommer 2023 kein Boot gekauft haben, aber im vorangegangenen Winter (d. h. Dezember 2022 bis März 2023) ein Boot gekauft haben. Die Abfrage, um diesen Bericht zu erhalten, lautet: SELECT * FROM client c1 WHERE EXISTS ( SELECT * FROM sale s1 JOIN product p1 ON p1.product_id = s1.product_id WHERE c1.client_id = s1.client_id AND p1.product_type = 'Boat' AND s1.sale_date >= '2022-12-21' AND s1.sale_date <= '2023-03-20' -- winter ) AND NOT EXISTS ( SELECT * FROM sale s2 JOIN product p1 ON p1.product_id = s2.product_id WHERE c1.client_id = s2.client_id AND p1.product_type = 'Boat' AND s2.sale_date >= '2023-6-21' AND s2.sale_date <= '2023-09-20' -- summer ) ; Ergebnisse: client_idClient_nameCountry 11Samid A.Kuwait Nach den beiden vorangegangenen Beispielen sollte dieses Beispiel nicht allzu schwer zu verstehen sein; es ist die Kombination aus beiden. Die Idee ist, den gesamten Datensatz (SELECT *) aus der Tabelle client Tabelle auszuwählen und dann eine EXISTS zu verwenden, um zu überprüfen, ob ein Boot im letzten Winter gekauft wurde. Danach verwenden wir NOT EXISTS, um zu prüfen, dass im vergangenen Sommer kein Boot gekauft wurde. Beachten Sie, dass beide Unterabfragen ein JOIN zwischen den sale und product steht, weil wir die Spalten product_type und sale_date in den WHERE Bedingungen verwenden müssen. An dieser Stelle möchte ich etwas über korrelierte Unterabfragen klarstellen. Wir haben erwähnt, dass korrelierte Unterabfragen für jeden Zeilenkandidaten ein Mal ausgeführt werden. Diese Tatsache kann sich auf die Leistung der gesamten Abfrage auswirken, insbesondere wenn wir mit großen Tabellen arbeiten. Zusammenfassend lässt sich sagen, dass der Operator EXISTS (und korrelierte Unterabfragen) eine leistungsstarke SQL-Ressource für bestimmte Arten von Abfragen ist. Wir sollten jedoch korrelierte Unterabfragen vermeiden, wenn wir mit großen Tabellen arbeiten. Üben des EXISTS-Operators Wie bei vielen anderen Computersprachen ist das Erlernen von SQL durch Übungen eine der besten Methoden, um Fähigkeiten zu erwerben. In diesem Abschnitt zeige ich drei EXISTS Operator-Übungen von unterschiedlicher Komplexität. Übung 1: Alte Befehle Übung: Der Inhaber des Unternehmens möchte wissen, welche Produkte (Autos oder Boote) in den letzten 365 Tagen nicht bestellt wurden. Lösung: SELECT p1.product_name FROM product p1 WHERE NOT EXISTS ( SELECT 1 FROM sale s WHERE s.product_id = p1.product_id AND s.sale_date >= CURRENT_DATE - 365 ); Ergebnisse: Product_name Ferrari F20 Pagani Zonda Lamborghini B9 VanDutch 58 Erläuterung: Die Hauptabfrage verwendet die Tabelle product um die Spalte product_name zu erhalten. Die WHERE Klausel dieser Abfrage ist der Schlüsselteil. Sie hat eine NOT EXISTS Bedingung, die TRUE für die Produkte auswertet, die im letzten Jahr nicht verkauft wurden. Mit der Bedingung s.sale_date >= CURRENT_DATE - 365 in der Unterabfrage werden alle Zeilen des letzten Jahres abgerufen. Beachten Sie, dass die Unterabfrage eine Konstante ( 1 ) zurückgibt. Das liegt daran, dass es bei der Unterabfrage darauf ankommt, wie viele Zeilen sie zurückgibt, und nicht auf den Inhalt der zurückgegebenen Zeilen; daher können wir eine Spalte oder eine Konstante wie 1 verwenden. Übung 2: Käufer von Bootsmotoren Übung: Unser Unternehmen ist bekannt für die Herstellung eines Bootsmotors und wir haben einige Kunden, die nur dieses Produkt kaufen. Die Marketingabteilung möchte Kunden identifizieren, die nur Bootsmotoren kaufen, damit sie diese Kunden in einer Marketingkampagne ansprechen können. Lösung: SELECT * FROM client c1 WHERE EXISTS ( SELECT * FROM sale s1 -- they buy boat engines JOIN product p1 ON p1.product_id = s1.product_id WHERE c1.client_id = s1.client_id AND p1.product_name = 'Boat engine' ) AND NOT EXISTS ( SELECT * FROM sale s2 -- they never buy other product JOIN product p2 ON p2.product_id = s2.product_id WHERE c1.client_id = s2.client_id AND p2.product_name <> 'Boat engine' ); Ergebnisse: client_idClient_nameCountry 13Pierre B.France 14Abdul E.Kuwait Erläuterung: Diese Übung hat eine WHERE Klausel mit zwei Bedingungen. Die erste Bedingung verwendet einen EXISTS Operator, um zu überprüfen, ob der von der äußeren Abfrage ausgewählte Kunde einen Bootsmotor gekauft hat. Die zweite Bedingung WHERE verwendet NOT EXISTS, um zu überprüfen, dass derselbe Kunde (der von der äußeren Abfrage ausgewählte Kunde) noch nie eine andere Art von Produkt gekauft hat. Wenn Sie weitere Übungen zu Subqueries kennenlernen möchten, empfehle ich Ihnen den Artikel SQL Subquery Practice: 15 Exercises with Solutions. Übung 3: Nie gekauft Übung: Der Eigentümer des Unternehmens möchte einen Bericht über nie gekaufte Produkte erstellen. Der Bericht soll nur zwei Spalten enthalten: client_name und product_name. Der Inhalt des Berichts soll das Komplement der sale Tabelle sein. Mit anderen Worten: Wenn ein Kunde nie ein Produkt gekauft hat, dann muss das Paar aus client_name und product_name im Bericht enthalten sein. Lösung: Es gibt zwei Wege, diese Aufgabe zu lösen: Verwendung von NOT EXISTS. Verwendung des Mengenoperators EXCEPT (oder MINUS). Wir werden beide Ansätze zeigen. Lösung mit NOT EXISTS: SELECT c1.client_name, p1.product_name FROM client c1, product p1 WHERE NOT EXISTS ( SELECT 1 FROM sale s WHERE c1.client_id = s.client_id AND p1.product_id = s.product_id ) Teilweise Abfrageergebnisse: Client_nameProduct_name John F.Ferrari F20 John F.Pagani Zonda John F.Lamborghini B9 John F.VanDutch 56 Samid A.Lamborghini AX Samid A.Pagani Zonda Samid A.VanDutch 56 Samid A.Lamborghini B9 Samid A.Boat Engine Yamei 100 Samid A.Ferrari F20 Erläuterung: Der erste Punkt, den es zu verstehen gilt, ist das Ergebnis dieses Teils der Abfrage: SELECT c1.client_name, p1.product_name FROM client c1, product p1 Da wir die Tabellen nicht richtig verbinden client und productnicht richtig verbunden haben, ist das Ergebnis ein kartesisches Produkt - eine Menge aller möglichen <client_name, product_name> Paare. Sobald wir alle möglichen Paare haben, verwerfen wir diese Paare in der sale Tabelle zu verwerfen, indem wir den Operator NOT EXISTS verwenden. Lösung mit EXCEPT: SELECT c1.client_name, p1.product_name FROM client c1, product p1 EXCEPT SELECT client_name, product_name FROM sale s JOIN product p ON p.product_id = s.product_id JOIN client c ON c.client_id = s.client_id Erläuterung: Der erste Teil dieses Ansatzes ähnelt der vorherigen Lösung; wir erstellen alle möglichen Kunden-Produkt-Paare. Dann entfernen wir mit dem Operator EXCEPT die Paare, die sich in der sale Tabelle stehen. So erhalten wir die gesuchten Paare. Hier ist der Unterschied: Im zweiten Teil von EXCEPT müssen wir JOIN die sale Tabelle mit den product und client Tabellen. Erweitern Sie Ihre SQL EXISTS-Operator-Kenntnisse In diesem Artikel haben wir die Operatoren EXISTS und NOT EXISTS anhand mehrerer Beispiele behandelt. Wir haben auch die Vor- und Nachteile von korrelierten Unterabfragen erläutert. Lesern, die ihre SQL-Kenntnisse vertiefen wollen, empfehle ich den SQL-Praxis Titel. Sie werden Hunderte von Übungen zu SQL-Themen wie JOINs, GROUP BY, HAVING, Unterabfragen und sogar den EXISTS-Operator finden. Wenn Sie gerade erst mit SQL anfangen oder eine Auffrischung brauchen, empfehle ich unseren SQL für Anfänger Kurs. Wenn Sie Ihre SQL-Kenntnisse verbessern, investieren Sie in sich selbst! Tags: SQL-Operatoren