Sebuah LEFT JOIN harus diganti dengan OUTER APPLY dalam situasi berikut.
1. Jika kita ingin menggabungkan dua tabel berdasarkan TOP n hasil
Pertimbangkan jika kita perlu memilih Id dan Name dari Master dan dua tanggal terakhir untuk setiap Id dari Details tabel.
SELECT M.ID,M.NAME,D.PERIOD,D.QTY
FROM MASTER M
LEFT JOIN
(
SELECT TOP 2 ID, PERIOD,QTY
FROM DETAILS D
ORDER BY CAST(PERIOD AS DATE)DESC
)D
ON M.ID=D.ID
yang membentuk hasil berikut
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 | NULL | NULL |
| 3 | C | NULL | NULL |
x------x---------x--------------x-------x
Ini akan membawa hasil yang salah yaitu, hanya akan membawa dua data tanggal terbaru dari Details tabel terlepas dari Id padahal kita gabung dengan Id . Jadi solusi yang tepat adalah menggunakan OUTER APPLY .
SELECT M.ID,M.NAME,D.PERIOD,D.QTY
FROM MASTER M
OUTER APPLY
(
SELECT TOP 2 ID, PERIOD,QTY
FROM DETAILS D
WHERE M.ID=D.ID
ORDER BY CAST(PERIOD AS DATE)DESC
)D
Inilah cara kerjanya:Di LEFT JOIN , TOP 2 tanggal akan digabungkan ke MASTER hanya setelah menjalankan kueri di dalam tabel turunan D . Di OUTER APPLY , ia menggunakan bergabung dengan WHERE M.ID=D.ID di dalam OUTER APPLY , sehingga setiap ID di Master akan bergabung dengan TOP 2 tanggal yang akan membawa hasil berikut.
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 |
| 3 | C | NULL | NULL |
x------x---------x--------------x-------x
2. Saat kita membutuhkan LEFT JOIN fungsionalitas menggunakan functions .
OUTER APPLY dapat digunakan sebagai pengganti LEFT JOIN ketika kita perlu mendapatkan hasil dari Master tabel dan functions .
SELECT M.ID,M.NAME,C.PERIOD,C.QTY
FROM MASTER M
OUTER APPLY dbo.FnGetQty(M.ID) C
Dan fungsinya ada di sini.
CREATE FUNCTION FnGetQty
(
@Id INT
)
RETURNS TABLE
AS
RETURN
(
SELECT ID,PERIOD,QTY
FROM DETAILS
WHERE example@sqldat.com
)
yang menghasilkan hasil berikut
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 |
| 3 | C | NULL | NULL |
x------x---------x--------------x-------x
3. Pertahankan NULL nilai saat membatalkan putaran
Pertimbangkan Anda memiliki tabel di bawah ini
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
Saat Anda menggunakan UNPIVOT untuk membawa FROMDATE DAN TODATE ke satu kolom, itu akan menghilangkan NULL nilai secara default.
SELECT ID,DATES
FROM MYTABLE
UNPIVOT (DATES FOR COLS IN (FROMDATE,TODATE)) P
yang menghasilkan hasil di bawah ini. Perhatikan bahwa kami melewatkan catatan Id nomor 3
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 |
x------x-------------x
Dalam kasus seperti itu, sebuah APPLY dapat digunakan (baik CROSS APPLY atau OUTER APPLY , yang dapat dipertukarkan).
SELECT DISTINCT ID,DATES
FROM MYTABLE
OUTER APPLY(VALUES (FROMDATE),(TODATE))
COLUMNNAMES(DATES)
yang membentuk hasil berikut dan mempertahankan Id dimana nilainya 3
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