Auswählen nur der ersten Zeile aus einer verwandten Tabelle in SQL-Joins
Datenbankverknüpfungen rufen häufig mehrere übereinstimmende Zeilen aus verwandten Tabellen ab. Dieser Artikel befasst sich mit dem Szenario, in dem Sie die Verknüpfung auf eine einzelne Zeile pro übergeordnetem Datensatz beschränken müssen, selbst wenn mehrere Übereinstimmungen vorhanden sind. Dies verhindert doppelte Ergebnisse in Ihrer Abfrageausgabe.
Die Herausforderung
Betrachten Sie zwei Tabellen: Orders
und LineItems
. Normalerweise besteht eine Bestellung aus einer Werbebuchung, einige Bestellungen können jedoch mehrere enthalten. Bei der Anzeige von Bestelldetails ist es wichtig, nur eine Werbebuchung pro Bestellung anzuzeigen, da sonst die Ergebnisse durch Duplikate verfälscht werden.
Erstansatz (und sein Scheitern)
Ein naiver Versuch, TOP 1
direkt im Join zu verwenden, schlägt fehl, weil die innere Abfrage nicht auf die Spalten der äußeren Tabelle zugreifen kann (wie OrderID
).
Die Lösung: CROSS APPLY und INNER JOIN
Der effektivste Ansatz verwendet CROSS APPLY
(verfügbar in SQL Server 2005 und höher) oder ein cleveres INNER JOIN
für ältere Versionen.
Verwenden von CROSS APPLY (SQL Server 2005 und höher)
CROSS APPLY
generiert ein Rowset für jede Zeile in der äußeren Tabelle und ermöglicht so eine korrelierte Unterabfrage. Diese Unterabfrage filtert dann eine einzelne Zeile aus der zugehörigen Tabelle und wählt sie aus.
<code class="language-sql">SELECT Orders.OrderNumber, LineItems2.Quantity, LineItems2.Description FROM Orders CROSS APPLY ( SELECT TOP 1 LineItems.Quantity, LineItems.Description FROM LineItems WHERE LineItems.OrderID = Orders.OrderID ) LineItems2</code>
Verwendung von INNER JOIN (SQL Server vor 2005)
Bei älteren SQL Server-Versionen ohne CROSS APPLY
erzielt ein INNER JOIN
mit einer Unterabfrage das gleiche Ergebnis:
<code class="language-sql">SELECT Orders.OrderNumber, LineItems.Quantity, LineItems.Description FROM Orders INNER JOIN LineItems ON LineItems.LineItemGUID = ( SELECT TOP 1 LineItemGUID FROM LineItems WHERE OrderID = Orders.OrderID )</code>
Wichtiger Hinweis zum Determinismus:
Die TOP 1
-Klausel ist ohne eine ORDER BY
-Klausel von Natur aus nicht deterministisch. Um konsistente Ergebnisse zu gewährleisten (d. h. immer die Auswahl des gleichen „ersten“ Zeilenelements), fügen Sie eine ORDER BY
-Klausel innerhalb der inneren Abfrage hinzu (z. B. ORDER BY LineItems.SomeColumn
). Dies gewährleistet eine vorhersehbare Auswahl der Werbebuchung.
Das obige ist der detaillierte Inhalt vonWie kann ich effizient nur mit der ersten Zeile einer verwandten Tabelle in SQL verknüpfen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!