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 [email protected]
)
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