Nehmen wir an, Sie haben zwei Tabellen.
MASTERTISCH
x------x--------------------x
| Id | Name |
x------x--------------------x
| 1 | A |
| 2 | B |
| 3 | C |
x------x--------------------x
DETAILS TABELLE
x------x--------------------x-------x
| Id | PERIOD | QTY |
x------x--------------------x-------x
| 1 | 2014-01-13 | 10 |
| 1 | 2014-01-11 | 15 |
| 1 | 2014-01-12 | 20 |
| 2 | 2014-01-06 | 30 |
| 2 | 2014-01-08 | 40 |
x------x--------------------x-------x
Es gibt viele Situationen, in denen wir Folgendes ersetzen müssen INNER JOIN
avec CROSS APPLY
.
1. Verbinden Sie zwei Tabellen basierend auf TOP n
Ergebnisse
Überlegen Sie, ob wir Folgendes auswählen müssen Id
y Name
de Master
und die letzten beiden Daten für jedes Id
de Details table
.
SELECT M.ID,M.NAME,D.PERIOD,D.QTY
FROM MASTER M
INNER JOIN
(
SELECT TOP 2 ID, PERIOD,QTY
FROM DETAILS D
ORDER BY CAST(PERIOD AS DATE)DESC
)D
ON M.ID=D.ID
Die obige Abfrage liefert das folgende Ergebnis.
x------x---------x--------------x-------x
| Id | Name | PERIOD | QTY |
x------x---------x--------------x-------x
| 1 | A | 2014-01-13 | 10 |
| 1 | A | 2014-01-12 | 20 |
x------x---------x--------------x-------x
Es wurden Ergebnisse für die letzten beiden Daten mit den letzten beiden Daten erzeugt Id
und verknüpfte diese Datensätze dann nur in der äußeren Abfrage auf Id
was falsch ist. Dies sollte beides zurückgeben Ids
1 und 2, aber es wurde nur 1 zurückgegeben, weil 1 die letzten beiden Daten enthält. Um dies zu erreichen, müssen wir Folgendes verwenden CROSS APPLY
.
SELECT M.ID,M.NAME,D.PERIOD,D.QTY
FROM MASTER M
CROSS APPLY
(
SELECT TOP 2 ID, PERIOD,QTY
FROM DETAILS D
WHERE M.ID=D.ID
ORDER BY CAST(PERIOD AS DATE)DESC
)D
und bildet das folgende Ergebnis.
x------x---------x--------------x-------x
| Id | Name | PERIOD | QTY |
x------x---------x--------------x-------x
| 1 | A | 2014-01-13 | 10 |
| 1 | A | 2014-01-12 | 20 |
| 2 | B | 2014-01-08 | 40 |
| 2 | B | 2014-01-06 | 30 |
x------x---------x--------------x-------x
Die Funktionsweise ist wie folgt. Die Abfrage innerhalb CROSS APPLY
auf die äußere Tabelle verweisen kann, wobei INNER JOIN
kann dies nicht tun (es wird ein Kompilierfehler ausgelöst). Bei der Suche nach den letzten beiden Daten erfolgt die Verknüpfung innerhalb von CROSS APPLY
d.h., WHERE M.ID=D.ID
.
2. Wenn wir brauchen INNER JOIN
Funktionalität mit Hilfe von Funktionen.
CROSS APPLY
kann als Ersatz verwendet werden für INNER JOIN
wenn wir ein Ergebnis von Master
Tisch und eine function
.
SELECT M.ID,M.NAME,C.PERIOD,C.QTY
FROM MASTER M
CROSS APPLY dbo.FnGetQty(M.ID) C
Und hier ist die Funktion
CREATE FUNCTION FnGetQty
(
@Id INT
)
RETURNS TABLE
AS
RETURN
(
SELECT ID,PERIOD,QTY
FROM DETAILS
WHERE ID=@Id
)
was zu folgendem Ergebnis führt
x------x---------x--------------x-------x
| Id | Name | PERIOD | QTY |
x------x---------x--------------x-------x
| 1 | A | 2014-01-13 | 10 |
| 1 | A | 2014-01-11 | 15 |
| 1 | A | 2014-01-12 | 20 |
| 2 | B | 2014-01-06 | 30 |
| 2 | B | 2014-01-08 | 40 |
x------x---------x--------------x-------x
ZUSÄTZLICHER VORTEIL VON CROSS-APPLICATION
APPLY
kann als Ersatz verwendet werden für UNPIVOT
. Entweder CROSS APPLY
o OUTER APPLY
verwendet werden, die austauschbar sind.
Nehmen wir an, Sie haben die folgende Tabelle (mit dem Namen MYTABLE
).
x------x-------------x--------------x
| Id | FROMDATE | TODATE |
x------x-------------x--------------x
| 1 | 2014-01-11 | 2014-01-13 |
| 1 | 2014-02-23 | 2014-02-27 |
| 2 | 2014-05-06 | 2014-05-30 |
| 3 | NULL | NULL |
x------x-------------x--------------x
Die Abfrage lautet wie folgt.
SELECT DISTINCT ID,DATES
FROM MYTABLE
CROSS APPLY(VALUES (FROMDATE),(TODATE))
COLUMNNAMES(DATES)
was Ihnen das Ergebnis liefert
x------x-------------x
| Id | DATES |
x------x-------------x
| 1 | 2014-01-11 |
| 1 | 2014-01-13 |
| 1 | 2014-02-23 |
| 1 | 2014-02-27 |
| 2 | 2014-05-06 |
| 2 | 2014-05-30 |
| 3 | NULL |
x------x-------------x