Unterabfragen (Unterabfragen) in SQL Server
- 12-09-2022
- Toanngo92
- 0 Comments
Mục lục
Unterabfragen (Unterabfragen)
Sie können eine SELECT-Anweisung oder eine Abfrage verwenden, um Datensätze zurückzugeben, die als Kriterien für eine andere SELECT-Anweisung oder Abfrage verwendet werden. Die äußere Abfrage wird als übergeordnete Abfrage und die innere Abfrage als Unterabfrage bezeichnet. Der Zweck einer Unterabfrage besteht darin, Ergebnisse an die äußere Abfrage zurückzugeben. Mit anderen Worten, die innere Abfrageanweisung muss die Spalte oder Spalten zurückgeben, die in den Kriterien der äußeren Abfrage verwendet werden.
Die einfachste Form einer Unterabfrage ist eine Abfrage, die nur eine Spalte zurückgibt. Die übergeordnete Abfrage kann die Ergebnisse dieser Unterabfrage mit dem „=“ verwenden. Syntax:
SELECT <ColumnName> FROM <table> WHERE <ColumnName> = (SELECT <ColumnName> FROM <Table> WHERE <ColumnName> = <Condition>)
In einer Unterabfrage wird zuerst die innerste SELECT-Anweisung ausgeführt und ihr Ergebnis als Kriterium für die äußere SELECT-Anweisung übergeben.
Stellen Sie sich eine Situation vor, in der es notwendig ist, die Fälligkeits- und Lieferdaten der letzten Bestellungen zu bestimmen.
Zum Beispiel:
SELECT DueDate,ShipDate FROM Sales.SalesOrderHeader WHERE Sales.SalesOrderHeader.OrderDate = (SELECT MAX(OrderDate) FROM Sales.SalesOrderHeader)
Hier wurde eine Unterabfrage verwendet, um die gewünschte Ausgabe zu erzielen. Die innere Abfrage oder Unterabfrage ruft das letzte Bestelldatum ab. Dieses Ergebnis wird dann an eine externe Abfrage weitergegeben, die das Fälligkeitsdatum und das Lieferdatum für alle Bestellungen anzeigt, Bestellungen, die an diesem bestimmten Tag ausgeführt wurden.
Basierend auf den von der inneren Abfrage zurückgegebenen Ergebnissen kann eine Unterabfrage entweder als skalare Unterabfrage ( skalar ) oder als mehrwertige Abfrage ( mehrwertig ) klassifiziert werden.
Folgende Beschreibungen stehen zur Verfügung:
- Die skalare Unterabfrage gibt einen einzelnen Wert zurück. Hier muss die äußere Abfrage geschrieben werden, um ein einzelnes Ergebnis zu verarbeiten.
- Die mehrwertige Unterabfrage gibt das gleiche Ergebnis zurück wie eine einspaltige Tabelle. Hier muss die äußere Abfrage geschrieben werden, um mehrere mögliche Ergebnisse zu verarbeiten.
Arbeiten mit mehrwertigen Abfragen
Wenn der Operator „=“ mit einer Unterabfrage verwendet wird, muss die Unterabfrage einen einzelnen Skalarwert zurückgeben. Wenn mehr als ein Wert zurückgegeben wird, tritt ein Fehler auf und die Abfrage wird nicht verarbeitet. In solchen Fällen können die Schlüsselwörter ANY, ALL, IN und EXISTS mit der WHERE-Klausel der SELECT-Anweisung verwendet werden, wenn die Abfrage eine Spalte, aber eine oder mehrere Zeilen zurückgibt.
Diese Schlüsselwörter, auch Prädikate genannt, werden bei mehrwertigen Abfragen verwendet. Bedenken Sie beispielsweise, dass alle Vor- und Nachnamen von Mitarbeitern mit der Berufsbezeichnung „Forschungs- und Entwicklungsleiter“ angezeigt werden müssen. Hier kann die innere Abfrage mehr als eine Zeile zurückgeben, da es mehrere Mitarbeiter mit dieser Berufsbezeichnung geben kann. Um sicherzustellen, dass die äußere Abfrage die Ergebnisse der inneren Abfrage verwenden kann, muss das Schlüsselwort IN verwendet werden.
Zum Beispiel:
SELECT FirstName,LastName FROM Person.Person WHERE Person.Person.BusinessEntityID IN (SELECT BusinessEntityID FROM HumanResources.Employee WHERE JobTitle='Research and Development Manager');
Welches der SOME- oder ANY -Schlüsselwörter wird als wahr ausgewertet, wenn das Ergebnis eine innere Abfrage ist, die mindestens eine Zeile enthält, die dem Vergleich entspricht. Vergleicht einen Skalarwert mit einer Wertespalte. SOME und ANY sind äquivalent, beide geben dasselbe Ergebnis zurück. Sie werden selten verwendet.
Einige Richtlinien bei der Verwendung von Unterabfragen:
- Die Datentypen ntext, text, image können nicht in SELECT in Unterabfragen verwendet werden
- Die mit dem Vergleichsoperator eingeleitete SELECT-Liste der Unterabfrage kann nur einen Ausdruck oder Spaltennamen haben.
- Unterabfragen können beim Arbeiten mit Vergleichsoperatoren mit ANY- oder ALL-Schlüsselwörtern keine GROUP BY- und HAVING-Klauseln verwenden
- Sie können das Schlüsselwort DISTINCT nicht mit Unterabfragen verwenden, die eine GROUP BY .-Klausel enthalten
- Sie können ORDER BY nur dann angeben, wenn TOP auch angegeben ist, wenn Sie eine Unterabfrage verwenden
Neben skalaren und mehrwertigen Unterabfragen können Sie auch zwischen unabhängigen Unterabfragen und korrelierten Unterabfragen wählen. Sie sind wie folgt definiert:
- Die eigenständige Unterabfrage wird als eigenständige Abfrage ohne Abhängigkeit von der externen Abfrage geschrieben. Eine unabhängige Unterabfrage wird einmal verarbeitet, wenn die äußere Abfrage ausgeführt wird, und ihre Ergebnisse werden an die äußere Abfrage übergeben.
- Die zugehörigen Unterabfragen beziehen sich auf eine oder mehrere Spalten der äußeren Abfrage und hängen daher von der äußeren Abfrage ab. Die zugehörigen Unterabfragen können nicht getrennt von der äußeren Abfrage ausgeführt werden.
Das Schlüsselwort EXISTS wird mit der Unterabfrage verwendet, um zu prüfen, ob die von der Unterabfrage zurückgegebene Zeile vorhanden ist. Es gibt keine Daten zurück und gibt TRUE oder FALSE zurück
Die Syntax der Unterabfrage, die das Schlüsselwort EXISTS enthält:
SELECT <ColumnName> FROM <table> WHERE [NOT] EXISTS (subquery_statement)
Zum Beispiel:
use AdventureWorks2019 go SELECT FirstName,LastName FROM Person.Person AS p WHERE EXISTS (SELECT * FROM HumanResources.Employee AS e WHERE JobTitle='Research and Development Manager' AND p.BusinessEntityID=e.BusinessEntityID )
Hier ruft die innere Unterabfrage alle Datensätze ab, die mit der Berufsbezeichnung „Forschungs- und Entwicklungsmanager“ übereinstimmen, und die BusinessEntityID hat eine BusinessEntityID, die mit diesem Datensatz in der Person-Tabelle übereinstimmt. Wenn es keine Datensätze gibt, die diesen beiden Bedingungen entsprechen, gibt die innere Unterabfrage keine Zeilen zurück. Der folgende Code gibt jedoch zwei Zeilen zurück, da die angegebenen Bedingungen erfüllt sind.
In ähnlicher Weise können Sie das Schlüsselwort NOT EXISTS verwenden, das die negative Klausel von EXISTS ist.
Verschachtelte Unterabfragen (Verschachtelte Unterabfragen)
Eine Unterabfrage, die in einer anderen Unterabfrage definiert ist, wird als verschachtelte Unterabfrage bezeichnet . In Anbetracht der Situation, in der Sie die Namen von Personen aus Kanada in adventureworks2019 abrufen und anzeigen möchten, gibt es keine direkte Möglichkeit, diese Informationen abzurufen, da die Tabelle „Sales.SalesTerritory“ nicht mit der Tabelle „Person.Person“ verknüpft ist. Daher kann eine verschachtelte Unterabfrage die Lösung sein.
Zum Beispiel:
SELECT LastName, FirstName FROM Person.Person WHERE BusinessEntityID IN (SELECT BusinessEntityID FROM Sales.SalesPerson WHERE TerritoryID IN (SELECT TerritoryID FROM Sales.SalesTerritory WHERE Name='Canada'))
Korrelierte Abfragen (Verwandte Abfragen)
Bei Mehrfachabfragen mit Unterabfragen wird die Unterabfrage nur einmal ausgewertet, um die für die übergeordnete Abfrage erforderlichen Werte bereitzustellen. Dies liegt daran, dass sich die Unterabfrage in den meisten Abfragen nicht auf die übergeordnete Abfrage bezieht, sodass der Wert in der Unterabfrage gleich bleibt.
Wenn die Unterabfrage jedoch auf die übergeordnete Abfrage verweist, muss die Unterabfrage für jede Iteration in der übergeordneten Abfrage neu ausgewertet werden. Dies liegt daran, dass die Suchkriterien in der Unterabfrage vom Wert eines bestimmten Datensatzes in der übergeordneten Abfrage abhängen.
Wenn eine Unterabfrage Parameter von der übergeordneten Abfrage erhält, wird sie als zugehörige Unterabfrage bezeichnet. Stellen Sie sich eine Situation vor, in der Sie alle BusinessEntityIDs von Personen abrufen möchten, deren Kontaktinformationen zuletzt nach 2012 geändert wurden. Dazu können Sie die zugehörige Unterabfrage wie folgt verwenden:
SELECT a.BusinessEntityID FROM Person.BusinessEntityContact a WHERE a.ContactTypeID IN (SELECT c.ContactTypeID FROM Person.ContactType c WHERE YEAR (a.ModifiedDate) >= 12)
Im Code-Snippet ruft die innere Abfrage die Kontakttyp-IDs für alle Personen ab, deren Kontaktinformationen zuletzt nach 2012 geändert wurden. Diese Ergebnisse werden dann an die äußere Abfrage übergeben, die Folgendes ergibt: Dies stimmt mit der ContactTypeID in der Person.BusinessEntityContact-Tabelle überein.