MySQL Unterabfrage mit Beispielen

โšก Intelligente Zusammenfassung

MySQL Die SubQuery-Syntax platziert eine SELECT-Anweisung innerhalb einer anderen, sodass das Ergebnis der inneren Abfrage die รคuรŸere Abfrage speist. Diese Erklรคrung behandelt skalare, zeilenbezogene und tabellenbezogene Unterabfragen, die Ausfรผhrungsreihenfolge, praktische Beispiele und den Leistungsvergleich mit JOIN-Operationen.

  • ๐Ÿ” Kerndefinition: Eine Unterabfrage ist eine SELECT-Anweisung, die in eine andere Abfrage eingebettet ist. Die innere Abfrage wird zuerst ausgefรผhrt, um der รคuรŸeren Abfrage Werte zu liefern.
  • ๐Ÿงฎ Skalare Unterabfrage: Gibt eine einzelne Zeile und eine einzelne Spalte zurรผck, daher passt es zu Vergleichsoperatoren wie gleich, grรถรŸer als oder kleiner als.
  • ๐Ÿ“‹ Zeilen- und Tabellenunterabfragen: Eine Zeilenunterabfrage gibt eine Zeile mit mehreren Spalten zurรผck, wรคhrend eine Tabellenunterabfrage viele Zeilen zurรผckgibt und mit dem IN-Operator arbeitet.
  • ๐Ÿงฉ Verschachtelungstiefe: Unterabfragen kรถnnen mehrere Ebenen tief verschachtelt werden, wodurch Werte wie das Mitglied mit dem hรถchsten Gehalt in einer einzigen Anweisung gefunden werden kรถnnen.
  • โœ๏ธ Jenseits von SELECT: Die Anweisungen INSERT, UPDATE und DELETE akzeptieren Unterabfragen, wodurch Massenรคnderungen ohne temporรคre Tabellen mรถglich sind.
  • โšก Leistungsregel: Ein JOIN ist in der Regel viel schneller als eine entsprechende Unterabfrage. Verwenden Sie Unterabfragen daher nur fรผr Logik, die ein JOIN nicht ausdrรผcken kann.

MySQL Unterabfrage

Was ist eine Unterabfrage in SQL?

A Unterabfrage Eine innere SELECT-Abfrage ist in einer anderen Abfrage enthalten. Sie dient รผblicherweise dazu, das Ergebnis der รคuรŸeren Abfrage zu ermitteln. Daher wertet die Datenbank die innere Abfrage zuerst aus und gibt deren Ergebnis anschlieรŸend an die รคuรŸere Abfrage weiter.

Die innere Abfrage wird als die innere Abfrage oder verschachtelte Abfrage, und die Anweisung, die sie enthรคlt, wird als die รคuรŸere AbfrageSchauen wir uns die Syntax der Unterabfrage an.

MySQL Unterabfrage

Das obige Diagramm zeigt die allgemeine Struktur der Anweisung: Die รคuรŸere SELECT-Anweisung gibt die Spalten an, die angezeigt werden sollen, und die in Klammern gesetzte innere SELECT-Anweisung gibt den Wert oder die Liste der Werte an, mit denen die WHERE-Klausel vergleicht.

Warum eine Unterabfrage verwenden?

Bevor wir uns die verschiedenen Typen ansehen, ist es hilfreich zu wissen, wann eine Unterabfrage in einer Anweisung ihren Platz verdient.

Eine Unterabfrage beantwortet eine Frage, deren Filterwert nicht im Voraus bekannt ist. Er muss aus den Daten selbst berechnet werden. Ein hรคufiger Kritikpunkt von Kunden der MyFlix-Videothek ist die geringe Anzahl an Filmtiteln. Das Management mรถchte Filme fรผr die Kategorie mit den wenigsten Titeln kaufen. Da niemand weiรŸ, welche Kategorie das ist, bis die Datenbank abgefragt wird, muss der Wert zunรคchst berechnet und dann als Filter verwendet werden.

Unterabfragen befinden sich beitractive aus drei praktischen Grรผnden:

  • Ablesbarkeit: Jeder Teil der Logik steht in einem eigenen geklammerten Block, sodass sich die Aussage eher wie eine Folge kleiner Fragen als wie ein komplexer Ausdruck liest.
  • Isolationswerte: Eine innere Abfrage kann separat ausgefรผhrt werden, um zu bestรคtigen, dass sie den erwarteten Wert zurรผckgibt, was das Testen und Debuggen erheblich vereinfacht.
  • Flexibilitรคt: Das gleiche Muster funktioniert in den WHERE-, HAVING-, SELECT- und FROM-Klauseln sowie innerhalb der INSERT-, UPDATE- und DELETE-Anweisungen.

Der Kompromiss besteht in der Geschwindigkeit, die im spรคteren Verlauf dieses Artikels im JOIN-Vergleich untersucht wird.

Arten von Unterabfragen in MySQL

MySQL Es werden drei Arten von Unterabfragen unterstรผtzt, wobei die Art des Ergebnisses der inneren Abfrage bestimmt wird. Jede Art wird im Folgenden anhand eines Beispiels mit der Datenbank myflixdb erlรคutert.

1) Skalare Unterabfrage

A Skalare Unterabfrage Gibt genau eine Zeile und eine Spalte zurรผck, also einen einzelnen Wert. Da das Ergebnis ein einzelner Wert ist, kann es รผberall dort verwendet werden, wo Literalwerte zulรคssig sind. Um auf das oben genannte MyFlix-Problem zurรผckzukommen: Sie kรถnnen eine Abfrage wie diese verwenden:

SELECT category_name FROM categories
WHERE category_id = (SELECT MIN(category_id) FROM movies);

Es liefert folgendes Ergebnis:

MySQL Unterabfrage

Mal sehen, wie diese Abfrage funktioniert.

MySQL Unterabfrage

Wie das Ausfรผhrungsdiagramm zeigt, MySQL erste Lรคufe SELECT MIN(category_id) FROM moviesDie Funktion empfรคngt einen Wert und fรผhrt erst dann die รคuรŸere Abfrage mit diesem Wert aus. Da nur ein einzelner Wert zurรผckgegeben wird, sind nur die Standardvergleichsoperatoren zulรคssig. =, <> (oder !=), >, >=, < und <=.

๐Ÿ’ก Tipp: Wenn eine Unterabfrage nach = gibt mehr als eine Zeile zurรผck. MySQL lรถst Fehler 1242 aus, Die Unterabfrage gibt mehr als eine Zeile zurรผck.. Schalten Sie den Operator um auf INoder die innere WHERE-Klausel verschรคrfen.

2) Zeilenunterabfrage

A Zeilen-Unterabfrage Die Abfrage gibt ebenfalls eine einzelne Zeile zurรผck, diese kann jedoch mehrere Spalten enthalten. Die รคuรŸere Abfrage vergleicht daher eine Zeile mit Werten mit einem Zeilenkonstruktor anstatt mit einem einzelnen Wert.

SELECT full_names, contact_number FROM members
WHERE (membership_number, gender) = (SELECT membership_number, gender FROM members WHERE full_names = 'Janet Jones');

Zulรคssige Operatoren sind die gleichen Vergleichsoperatoren wie oben aufgefรผhrt, die auf die gesamte Zeile gleichzeitig angewendet werden.

3) Tabellen-Unterabfrage

A Tabellenunterabfrage Gibt mehrere Zeilen und oft auch mehrere Spalten zurรผck, muss die รคuรŸere Abfrage einen Mengenoperator wie z. B. verwenden. IN, NOT IN, ANY, ALLden EXISTS.

Angenommen, Sie benรถtigen die Namen und Telefonnummern von Mitgliedern, die einen Film ausgeliehen, aber noch nicht zurรผckgegeben haben, um sie telefonisch daran zu erinnern. Sie kรถnnen eine Abfrage wie diese verwenden:

SELECT full_names, contact_number FROM members
WHERE membership_number IN (SELECT membership_number FROM movierentals WHERE return_date IS NULL);

MySQL Unterabfrage

Mal sehen, wie diese Abfrage funktioniert.

MySQL Unterabfrage

In diesem Fall liefert die innere Abfrage mehrere Ergebnisse, daher wird die Liste der Mitgliedsnummern an die IN Der Operator und alle zugehรถrigen Elemente werden zurรผckgegeben.

Verschachtelung von Unterabfragen รผber mehrere Ebenen

Bisher haben Sie zwei Ebenen kennengelernt. Eine Unterabfrage kann auch eine weitere Unterabfrage enthalten, wodurch eine dreifach verschachtelte Anweisung entsteht.

Angenommen, das Management mรถchte das Mitglied mit dem hรถchsten Beitragssatz belohnen. Wir kรถnnen eine Abfrage wie diese ausfรผhren:

SELECT full_names FROM members
WHERE membership_number = (SELECT membership_number FROM payments
    WHERE amount_paid = (SELECT MAX(amount_paid) FROM payments));

Die innerste Abfrage ermittelt die hรถchste Zahlung, die mittlere Abfrage wandelt diesen Betrag in eine Mitgliedsnummer um und die รคuรŸere Abfrage wandelt die Mitgliedsnummer in einen Namen um. Die obige Abfrage liefert folgendes Ergebnis:

MySQL Unterabfrage

Wie man Unterabfragen mit INSERT, UPDATE und DELETE verwendet

Unterabfragen sind nicht auf SELECT-Anweisungen beschrรคnkt. Das gleiche Klammermuster funktioniert auch innerhalb von Datenรคnderungsanweisungen, wodurch ein ganzer Satz von Zeilen in einem Durchlauf geรคndert werden kann, ohne eine temporรคre Tabelle zu erstellen.

INSERT mit einer Unterabfrage. Eine Unterabfrage kann die einzufรผgenden Zeilen liefern und kopiert Daten von einer Tabelle in eine andere. Die Spaltenliste der SELECT-Anweisung muss mit der Spaltenliste der INSERT-Anweisung รผbereinstimmen.

INSERT INTO vip_members (membership_number, full_names)
SELECT membership_number, full_names FROM members
WHERE membership_number IN (SELECT membership_number FROM payments WHERE amount_paid > 5000);

UPDATE mit einer Unterabfrage. Die innere Abfrage entscheidet hier, welche Zeilen betroffen sind. Das folgende Beispiel markiert alle Mitglieder, deren Miete noch aussteht.

UPDATE members
SET reminder_sent = 1
WHERE membership_number IN (SELECT membership_number FROM movierentals WHERE return_date IS NULL);

DELETE mit einer Unterabfrage. Das gleiche Prinzip entfernt Zeilen, die eine in einer zweiten Tabelle festgelegte Bedingung erfรผllen.

DELETE FROM members
WHERE membership_number NOT IN (SELECT membership_number FROM movierentals);

โš ๏ธ Warnung: MySQL Eine Anweisung, die eine Tabelle รคndert und innerhalb einer Unterabfrage in der FROM-Klausel Daten aus derselben Tabelle auswรคhlt, ist nicht zulรคssig. Falls der Fehler 1093 auftritt, schlieรŸen Sie die innere Abfrage in eine abgeleitete Tabelle ein, z. B. SELECT * FROM (SELECT ...) AS t, So dass MySQL Das Ergebnis wird ermittelt, bevor die ร„nderung angewendet wird. Es ist auรŸerdem ratsam, die innere SELECT-Anweisung zunรคchst separat auszufรผhren und die Zeilenanzahl zu bestรคtigen, bevor eine ร„nderung angewendet wird. AKTUALISIEREN oder die Lร–SCHEN in Produktion.

Unterabfragen vs. Joins

Sowohl eine Unterabfrage als auch ein JOIN kรถnnen Informationen aus mehr als einer Tabelle kombinieren, daher stellt sich die Frage, welche Methode man verwenden sollte.

Im Vergleich zu Joins sind Unterabfragen einfach zu verwenden und leicht lesbar. Sie sind nicht so kompliziert wie Joinsund werden daher hรคufig verwendet von SQL-Anfรคnger.

Unterabfragen weisen jedoch Leistungsprobleme auf. Die Verwendung eines Joins anstelle einer Unterabfrage kann die Leistung mitunter um das bis zu 500-Fache steigern, da der Optimierer einen Join in einem einzigen Durchlauf auflรถsen kann, anstatt die innere Anweisung wiederholt auszuwerten.

Vergleichspunkt Unterabfrage JOIN
Ablesbarkeit Hoch, da jeder Block eine Frage beantwortet Lower, da alle Tabellen in einer Klausel erscheinen
Leistung Langsamer, da die innere Abfrage mรถglicherweise fรผr jede รคuรŸere Zeile ausgefรผhrt wird. Schneller, oft um einen sehr groรŸen Teil.
Ergebnisspalten Es werden nur die Spalten der รคuรŸeren Tabelle zurรผckgegeben. Es kรถnnen Spalten aus jeder verknรผpften Tabelle zurรผckgegeben werden.
Typische Verwendung Filtern nach einem Wert, der zuerst berechnet werden muss Zusammenfรผhren verwandter Zeilen aus zwei oder mehr Tabellen
Lernkurve Sanft, vertraut fรผr Anfรคnger Steeper erfordert Kenntnisse รผber Verbindungsarten

Wenn Sie die Wahl haben, wird empfohlen, einen JOIN fรผr eine Unterabfrage zu verwenden. Unterabfragen sollten nur als Ausweichlรถsung verwendet werden, wenn Sie mit einer JOIN-Operation nicht das oben Genannte erreichen kรถnnen.

Unterabfragen vs. Joins

Unterabfragen lassen sich auรŸerdem leicht in einzelne logische Komponenten zerlegen, was sehr nรผtzlich ist, wenn testing und Debuggen der Abfragen.

Hรคufig gestellte Fragen

Eine korrelierte Unterabfrage bezieht sich auf eine Spalte der รคuรŸeren Abfrage und wird daher fรผr jede Zeile der รคuรŸeren Abfrage einmal ausgewertet. Eine nicht korrelierte Unterabfrage ist unabhรคngig und wird nur einmal ausgefรผhrt. Korrelierte Unterabfragen sind zwar leistungsstark, aber bei groรŸen Tabellen merklich langsamer.

Eine Unterabfrage kann in der WHERE-Klausel, der HAVING-Klausel, der SELECT-Liste oder der FROM-Klausel stehen, wo sie zu einer abgeleiteten Tabelle wird und einen Alias โ€‹โ€‹benรถtigt. Sie ist auch innerhalb von INSERT-, UPDATE- und DELETE-Anweisungen gรผltig.

Oft ja. KI-Assistenten, die in Editoren wie beispielsweise integriert sind MySQL Werkbank kann einen gleichwertigen Vorschlag unterbreiten. JOINVergleichen Sie immer die Zeilenanzahl und lesen Sie den EXPLAIN-Plan, bevor Sie dem Rewrite vertrauen, da die Behandlung von NULL-Werten unterschiedlich sein kann.

Ja. Text-zu-SQL-Assistenten wandeln Fragen wie โ€žWelche Kategorie hat die wenigsten Filme?โ€œ in eine verschachtelte SELECT-Anweisung um. Die Genauigkeit hรคngt vom verwendeten Schema ab. รœberprรผfen Sie daher die generierte Anweisung anhand der tatsรคchlichen Tabellennamen.

Der Fehler tritt auf, wenn eine nach einem Vergleichsoperator stehende Unterabfrage mehrere Zeilen zurรผckgibt. Ersetzen Sie den Operator durch IN, ANY oder EXISTS oder verschรคrfen Sie die innere WHERE-Klausel, sodass nur eine Zeile zurรผckgegeben wird.

Fassen Sie diesen Beitrag mit folgenden Worten zusammen: