Database
 sql >> Teknologi Basis Data >  >> RDS >> Database

Panduan Utama Anda untuk Bergabung dengan SQL:OUTER JOIN – Bagian 2

Outer join menjadi pusat perhatian hari ini. Dan ini adalah bagian 2 dari panduan utama Anda untuk bergabung dengan SQL. Jika Anda melewatkan bagian 1, ini tautannya.

Dari kelihatannya, luar adalah kebalikan dari batin. Namun, jika Anda menganggap bagian luar bergabung dengan cara ini, Anda akan bingung. Selain itu, Anda tidak perlu menyertakan kata luar dalam sintaks Anda secara eksplisit. Ini opsional!

Tapi sebelum kita masuk, mari kita bahas null tentang outer join.

Nulls dan OUTER JOIN

Saat Anda bergabung dengan 2 tabel, salah satu nilai dari salah satu tabel bisa menjadi nol. Untuk INNER JOIN, record dengan null tidak akan cocok, dan akan dibuang dan tidak akan muncul di kumpulan hasil. Jika Anda ingin mendapatkan catatan yang tidak cocok, satu-satunya pilihan Anda adalah OUTER JOIN.

Kembali ke antonim, bukankah itu kebalikan dari INNER JOIN? Tidak sepenuhnya, seperti yang akan Anda lihat di bagian berikutnya.

Semua Tentang SQL Server OUTER JOIN

Memahami gabungan luar dimulai dengan output. Berikut daftar lengkap dari apa yang dapat Anda harapkan:

  • Semua record yang cocok dengan kondisi atau predikat join. Itu ekspresi tepat setelah kata kunci ON, seperti output INNER JOIN. Kami menyebut masalah ini sebagai baris dalam .
  • Nilai non-NULL dari kiri tabel dengan pasangan nol dari kanan meja. Kami menyebut masalah ini sebagai baris luar .
  • Nilai non-NULL dari kanan tabel dengan pasangan nol dari kiri meja. Ini adalah bentuk lain dari baris luar.
  • Akhirnya, ini bisa menjadi kombinasi dari semua hal yang dijelaskan di atas.

Dengan daftar itu, kita dapat mengatakan bahwa OUTER JOIN mengembalikan baris dalam dan luar .

  • Inner – karena hasil yang tepat dari INNER JOIN bisa dikembalikan.
  • Luar – karena baris terluar bisa juga dikembalikan.

Ini adalah perbedaan dari INNER JOIN.

INNER GABUNG SAJA KEMBALI BARIS DALAM. OUTER JOIN DAPAT MENGEMBALIKAN BARIS DALAM DAN OUTER

Perhatikan bahwa saya menggunakan “can be” dan “can also be”. Itu tergantung pada klausa WHERE Anda (atau jika Anda pernah menyertakan klausa WHERE) jika mengembalikan baris dalam dan/atau luar.

Tapi dari pernyataan SELECT, bagaimana Anda bisa menentukan yang merupakan tabel kiri atau kanan ? Pertanyaan bagus!

Bagaimana Mengetahui Mana Tabel Kiri atau Kanan dalam Suatu Join?

Kita bisa menjawab pertanyaan ini dengan contoh:

SELECT *
FROM Table1 a
LEFT OUTER JOIN Table2 b on a.column1 = b.column1

Dari contoh di atas, Tabel1 adalah tabel kiri, dan Tabel2 adalah meja yang tepat. Sekarang, mari kita lihat contoh lain. Kali ini, ini adalah multi-gabung sederhana.

SELECT *
FROM Table1 a
LEFT OUTER JOIN Table2 b on a.column1 = b.column1
LEFT OUTER JOIN Table3 c on b.column2 = c.column1

Dalam hal ini, untuk mengetahui kiri atau kanan, ingatlah bahwa gabungan bekerja pada 2 tabel.

Tabel1 masih meja kiri, dan Tabel2 adalah meja yang tepat. Ini mengacu pada penggabungan 2 tabel:Tabel1 dan Tabel2 . Bagaimana dengan bergabung dengan Table2 dan Tabel3 ? Tabel2 menjadi tabel kiri, dan Tabel3 adalah tabel yang tepat.

Jika kita menambahkan tabel keempat, Tabel3 menjadi tabel kiri, dan Table4 adalah meja yang tepat. Tapi itu tidak berakhir di sana. Kita dapat menggabungkan tabel lain ke Tabel1 . Ini contohnya:

SELECT *
FROM Table1 a
LEFT OUTER JOIN Table2 b on a.column1 = b.column1
LEFT OUTER JOIN Table3 c on b.column2 = c.column1
LEFT OUTER JOIN Table4 d on c.column1 = d.column2
LEFT OUTER JOIN Table5 e on a.column2 = e.column1

Tabel1 adalah tabel kiri, dan Tabel5 adalah meja yang tepat. Anda juga dapat melakukan hal yang sama dengan tabel lainnya.

Oke, mari kita kembali ke daftar output yang diharapkan di atas. Kami juga dapat menurunkan tipe gabungan luar dari ini.

Jenis Sambungan Luar

Ada 3 jenis berdasarkan output OUTER JOIN.

GABUNG LUAR KIRI (GABUNG KIRI)

LEFT JOIN mengembalikan baris dalam + nilai Non-NULL dari kiri tabel dengan rekan nol tabel kanan. Oleh karena itu, LEFT JOIN karena tabel kiri adalah dominan dari dua tabel dalam gabungan yang memiliki nilai bukan nol.

LEFT OUTER JOIN CONTOH 1
-- Return all customerIDs with orders and no orders

USE AdventureWorks
GO

SELECT
 c.CustomerID
,soh.OrderDate
FROM Sales.Customer c
LEFT OUTER JOIN Sales.SalesOrderHeader soh ON c.CustomerID = soh.CustomerID 

Pada contoh di atas, Pelanggan adalah tabel kiri, dan SalesOrderHeader adalah meja yang tepat. Hasil kueri adalah 32.166 record – itu termasuk baris dalam dan luar. Anda dapat melihat sebagiannya pada Gambar 1:

Misalkan kita ingin mengembalikan baris terluar saja atau pelanggan tanpa pesanan. Untuk melakukannya, tambahkan klausa WHERE untuk menyertakan hanya baris dengan null dari SalesOrderHeader .

SELECT
 c.CustomerID
,soh.OrderDate
FROM Sales.Customer c
LEFT OUTER JOIN Sales.SalesOrderHeader soh ON c.CustomerID = soh.CustomerID
WHERE soh.SalesOrderID IS NULL

Kumpulan hasil yang saya dapatkan adalah 701 catatan . Semuanya menyukai OrderDate null dari Gambar 1.

Jika saya mendapatkan baris dalam saja, hasilnya akan menjadi 31.465 record . Saya bisa melakukannya dengan mengubah klausa WHERE untuk menyertakan SalesOrderIDs yang tidak nol. Atau saya dapat mengubah gabungan menjadi INNER JOIN dan menghapus klausa WHERE.

Untuk melihat apakah check out dari output contoh pertama tanpa klausa WHERE, mari kita jumlahkan recordnya.

Baris Dalam Baris Luar Total Baris
31.465 catatan 701 catatan 32.166 catatan

Dari Total Baris di atas dengan 32.166 catatan, Anda dapat melihat bahwa ia memeriksa dengan hasil contoh pertama. Ini juga menunjukkan cara kerja LEFT OUTER JOIN.

LEFT OUTER JOIN CONTOH 2

Kali ini, contohnya adalah multi-join. Perhatikan juga bahwa kita menghilangkan kata kunci OUTER.

-- show the people with and without addresses from AdventureWorks
USE AdventureWorks
GO

SELECT
 P.FirstName
,P.MiddleName
,P.LastName
,a.AddressLine1
,a.AddressLine2
,a.City
,adt.Name AS AddressType
FROM Person.Person p
LEFT JOIN Person.BusinessEntityAddress bea ON P.BusinessEntityID = bea.BusinessEntityID
LEFT JOIN Person.Address a ON bea.AddressID = a.AddressID
LEFT JOIN person.AddressType adt ON bea.AddressTypeID = adt.AddressTypeID 

Ini menghasilkan 19.996 catatan. Anda dapat memeriksa bagian dari output pada Gambar 2 di bawah ini. Catatan dengan AddressLine1 null null adalah baris luar. Di atasnya ada baris dalam.

GABUNG LUAR KANAN (GABUNG KANAN)

RIGHT JOIN mengembalikan baris dalam + nilai Non-NULL dari kanan tabel dengan rekan nol tabel kiri.

CONTOH GABUNG LUAR KANAN CONTOH 1
-- From the product reviews, return the products without product reviews
USE AdventureWorks
GO

SELECT
P.Name
FROM Production.ProductReview pr
RIGHT OUTER JOIN Production.Product p ON pr.ProductID = p.ProductID
WHERE pr.ProductReviewID IS NULL 

Gambar 3 menunjukkan 10 dari 501 record dalam kumpulan hasil.

Dalam contoh di atas, ProductReview adalah tabel kiri, dan Produk adalah meja yang tepat. Karena ini adalah RIGHT OUTER JOIN, kami bermaksud memasukkan nilai Non-NULL dari tabel kanan.

Namun, memilih antara LEFT JOIN atau RIGHT JOIN tergantung pada Anda. Mengapa? Karena Anda dapat mengekspresikan kueri, apakah LEFT atau RIGHT JOIN, dan mendapatkan hasil yang sama. Mari kita coba dengan LEFT JOIN.

-- return the products without product reviews using LEFT OUTER JOIN
USE AdventureWorks
GO

SELECT
P.Name
FROM Production.Product p
LEFT OUTER JOIN Production.ProductReview pr ON pr.ProductID = p.ProductID
WHERE pr.ProductReviewID IS NULL

Coba jalankan di atas, dan Anda akan mendapatkan hasil yang sama seperti pada Gambar 3. Namun menurut Anda, apakah Pengoptimal Kueri akan memperlakukannya secara berbeda? Mari kita cari tahu di Execution Plan keduanya pada Gambar 4.

Jika Anda baru dalam hal ini, ada beberapa kejutan dalam Rencana Eksekusi.

  1. Diagramnya terlihat sama, yaitu:coba Bandingkan Showplan , dan Anda akan melihat QueryPlanHash yang sama .
  2. Perhatikan diagram teratas dengan gabungan Gabung. Kami menggunakan RIGHT OUTER JOIN, tetapi SQL Server mengubahnya menjadi LEFT OUTER JOIN. Itu juga mengubah tabel kiri dan kanan. Itu membuatnya sama dengan kueri kedua dengan LEFT JOIN.

Seperti yang Anda lihat sekarang, hasilnya sama. Jadi, pilih OUTER JOIN mana yang lebih nyaman.

Mengapa SQL Server Mengubah RIGHT JOIN menjadi LEFT JOIN?

Mesin database tidak harus mengikuti cara Anda mengekspresikan gabungan logis. Selama itu dapat menghasilkan hasil yang benar dengan cara tercepat yang dianggap mungkin, itu akan membuat perubahan. Bahkan jalan pintas.

Jangan menyimpulkan bahwa RGHT JOIN itu buruk dan LEFT JOIN itu baik.

CONTOH GABUNG LUAR KANAN CONTOH 2

Lihat contoh di bawah ini:

-- Get the unassigned addresses and the address types with no addresses
SELECT
 P.FirstName
,P.MiddleName
,P.LastName
,a.AddressLine1
,a.AddressLine2
,a.City
,adt.Name AS AddressType
FROM Person.Person p
RIGHT JOIN Person.BusinessEntityAddress bea ON P.BusinessEntityID = bea.BusinessEntityID
RIGHT JOIN Person.Address a ON bea.AddressID = a.AddressID
RIGHT JOIN person.AddressType adt ON bea.AddressTypeID = adt.AddressTypeID
WHERE P.BusinessEntityID IS NULL 

Ada 2 hal yang bisa didapatkan dari query ini, seperti yang terlihat pada Gambar 5 di bawah ini:

Hasil kueri menunjukkan sebagai berikut:

  1. Alamat yang belum ditetapkan – catatan ini adalah alamat dengan nama nol.
  2. Jenis Alamat tanpa alamat. Jenis alamat Arsip, Penagihan, dan Utama tidak memiliki alamat yang sesuai. Itu dari catatan 817 hingga 819.

GABUNG LUAR LENGKAP (GABUNG LENGKAP)

FULL JOIN mengembalikan kombinasi baris dalam dan baris luar, kiri dan kanan.

-- Get people with and without addresses, unassigned addresses, and address types without addresses
SELECT
 P.FirstName
,P.MiddleName
,P.LastName
,a.AddressLine1
,a.AddressLine2
,a.City
,adt.Name AS AddressType
FROM Person.Person p
FULL JOIN Person.BusinessEntityAddress bea ON P.BusinessEntityID = bea.BusinessEntityID
FULL JOIN Person.Address a ON bea.AddressID = a.AddressID
FULL JOIN person.AddressType adt ON bea.AddressTypeID = adt.AddressTypeID

Kumpulan hasil mencakup 20.815 catatan. Seperti yang Anda harapkan, ini adalah jumlah total catatan dari kumpulan hasil INNER JOIN, LEFT JOIN, dan RIGHT JOIN.

LEFT dan RIGHT JOIN menyertakan klausa WHERE untuk hanya menampilkan hasil dengan nol di tabel kiri atau kanan.

INNER JOIN KIRI GABUNG
(DI MANA a.AddressID IS NULL)
BENAR BERGABUNG
(DI MANA P.BusinessEntityID ADALAH NULL)
TOTAL (Sama dengan FULL JOIN)
18.798 catatan 1.198 catatan 819 catatan 20.815 catatan

Perhatikan bahwa FULL JOIN dapat menghasilkan kumpulan hasil besar dari tabel besar. Jadi, gunakan hanya saat Anda membutuhkannya saja.

Penggunaan Praktis OUTER JOIN

Jika Anda masih ragu kapan Anda bisa dan harus menggunakan OUTER JOIN, berikut beberapa idenya.

Outer Bergabung dengan Output Baik Baris Dalam dan Baris Luar

Contohnya dapat berupa:

  • Daftar alfabetis pesanan pelanggan berbayar dan tidak berbayar.
  • Daftar alfabetis karyawan dengan catatan keterlambatan atau tidak ada keterlambatan.
  • Daftar pemegang polis yang memperbarui dan tidak memperbarui polis asuransi terbaru mereka.

Hanya Menggabungkan Baris Luar Keluaran Itu

Contohnya meliputi:

  • daftar abjad karyawan tanpa catatan keterlambatan untuk penghargaan nol-keterlambatan
  • daftar wilayah tanpa pelanggan
  • daftar agen penjualan tanpa penjualan produk tertentu
  • mendapatkan hasil dari nilai yang hilang, seperti tanggal tanpa pesanan penjualan dalam periode tertentu (contoh di bawah)
  • simpul tanpa anak dalam hubungan orangtua-anak (contoh di bawah)

Mendapatkan Hasil dari Nilai yang Hilang

Misalkan Anda perlu membuat laporan. Laporan itu harus menunjukkan jumlah hari untuk setiap bulan dalam periode tertentu di mana tidak ada pesanan. SalesOrderHeader di AdventureWorks berisi TanggalPesanan , tetapi mereka tidak memiliki tanggal tanpa pesanan. Apa yang bisa kamu lakukan?

1. Buat Tabel Semua Tanggal dalam Satu Periode

Contoh skrip di bawah ini akan membuat tabel tanggal untuk keseluruhan tahun 2014:

DECLARE @StartDate date = '20140101', @EndDate date = '20141231';

CREATE TABLE dbo.Dates
(
	d DATE NOT null PRIMARY KEY
)

WHILE @StartDate <= @EndDate
BEGIN
  INSERT Dates([d]) SELECT @StartDate;
  SET @StartDate = DATEADD(DAY, 1, @StartDate);
END

SELECT d FROM Dates ORDER BY [d];
2. Gunakan LEFT JOIN untuk Menampilkan Hari-hari Tanpa Pesanan
SELECT
 MONTH(d.d) AS [month]
,YEAR(d.d) AS [year]
,COUNT(*) AS NoOrderDays
FROM Dates d
LEFT JOIN Sales.SalesOrderHeader soh ON d.d = soh.OrderDate
WHERE soh.OrderDate IS NULL
GROUP BY YEAR(d.d), MONTH(d.d)
ORDER BY [year], [month]

Kode di atas menghitung jumlah hari ketika tidak ada pesanan yang dibuat. SalesOrderHeader berisi tanggal dengan pesanan. Jadi, null yang dikembalikan dalam gabungan akan dihitung sebagai hari tanpa pesanan.

Sedangkan jika ingin mengetahui tanggal pastinya, Anda bisa menghilangkan hitungan dan pengelompokannya.

SELECT
 d.d
,soh.OrderDate
FROM Dates d
LEFT JOIN Sales.SalesOrderHeader soh ON d.d = soh.OrderDate
WHERE soh.OrderDate IS NULL

Atau, jika Anda ingin menghitung pesanan dalam periode tertentu dan melihat tanggal mana yang tidak memiliki pesanan, berikut caranya:

SELECT DISTINCT
 D.d AS SalesDate
,COUNT(soh.OrderDate) AS NoOfOrders
FROM Dates d
LEFT JOIN Sales.SalesOrderHeader soh ON d.d = soh.OrderDate
WHERE d.d BETWEEN '02/01/2014' AND '02/28/2014'
GROUP BY d.d
ORDER BY d.d

Kode di atas menghitung pesanan untuk Februari 2014. Lihat hasilnya:

Mengapa itu menyoroti 3 Februari 2014? Dalam salinan AdventureWorks saya, tidak ada pesanan penjualan untuk tanggal tersebut.

Sekarang, perhatikan COUNT(soh.OrderDate) dalam kode. Nanti, kami akan mengklarifikasi mengapa ini sangat penting.

Mendapatkan Node Tanpa Anak dalam Hubungan Orangtua-Anak

Terkadang kita perlu mengetahui node tanpa anak dalam hubungan parent-child.

Mari kita gunakan database yang telah saya gunakan dalam artikel saya tentang HierarchyID. Anda perlu mendapatkan node tanpa anak dalam tabel hubungan induk-anak menggunakan self-join.

SELECT 
 r1.RankParentId
,r1.Rank AS RankParent
,r.RankId
FROM Ranks r
RIGHT JOIN Ranks r1 ON r.RankParentId = r1.RankId
WHERE r.RankId is NULL 

Peringatan dalam Menggunakan OUTER JOIN

Karena OUTER JOIN dapat mengembalikan baris dalam seperti INNER JOIN, ini dapat membingungkan. Masalah performa juga bisa muncul. Jadi, perhatikan 3 poin di bawah ini (saya kembali ke sana dari waktu ke waktu – saya tidak semakin muda, jadi saya juga lupa).

Memfilter Tabel Kanan pada LEFT JOIN dengan Nilai Bukan Null pada Klausa WHERE

Ini bisa menjadi masalah jika Anda menggunakan LEFT OUTER JOIN tetapi memfilter tabel kanan dengan nilai non-null dalam klausa WHERE. Alasannya, itu akan menjadi setara secara fungsional dengan INNER JOIN. Perhatikan contoh di bawah ini:

USE AdventureWorks
GO

SELECT
 P.FirstName
,P.MiddleName
,P.LastName
,a.AddressLine1
,a.AddressLine2
,a.City
,adt.Name AS AddressType
FROM Person.Person p
LEFT JOIN Person.BusinessEntityAddress bea ON P.BusinessEntityID = bea.BusinessEntityID
LEFT JOIN Person.Address a ON bea.AddressID = a.AddressID
LEFT JOIN person.AddressType adt ON bea.AddressTypeID = adt.AddressTypeID
WHERE bea.AddressTypeID = 5 

Dari kode di atas, mari kita periksa 2 tabel:Orang dan BusinessEntityAddress . Orangnya adalah tabel kiri, dan BusinessEntityAddress adalah tabel yang tepat.

LEFT JOIN digunakan, jadi diasumsikan BusinessEntityID null null di suatu tempat di BusinessEntityAddress . Di sini, perhatikan klausa WHERE. Ini memfilter tabel yang tepat dengan AddressTypeID =5. Ini benar-benar membuang semua baris luar di BusinessEntityAddress .

Ini dapat berupa salah satu dari ini:

  • Pengembang sedang menguji sesuatu di hasil tetapi lupa menghapusnya.
  • INNER JOIN dimaksudkan, tetapi untuk beberapa alasan, LEFT JOIN digunakan.
  • Pengembang tidak memahami perbedaan antara LEFT JOIN dan INNER JOIN. Dia menganggap salah satu dari 2 akan berhasil, dan itu tidak masalah karena hasilnya sama dalam kasus ini.

Salah satu dari 3 di atas buruk, tetapi entri ketiga memiliki implikasi lain. Mari kita bandingkan kode di atas dengan padanan INNER JOIN:

SELECT
 P.FirstName
,P.MiddleName
,P.LastName
,a.AddressLine1
,a.AddressLine2
,a.City
,adt.Name AS AddressType
FROM Person.Person p
INNER JOIN Person.BusinessEntityAddress bea ON P.BusinessEntityID = bea.BusinessEntityID
INNER JOIN Person.Address a ON bea.AddressID = a.AddressID
INNER JOIN person.AddressType adt ON bea.AddressTypeID = adt.AddressTypeID
WHERE bea.AddressTypeID = 5

Tampilannya mirip dengan kode sebelumnya kecuali untuk jenis join. Hasilnya juga sama, tetapi Anda harus memperhatikan pembacaan logis di STATISTICS IO:

Pada Gambar 7, statistik I/O pertama berasal dari penggunaan INNER JOIN. Total pembacaan logis adalah 177. Namun, statistik kedua adalah untuk LEFT JOIN dengan nilai pembacaan logis yang lebih tinggi dari 223. Dengan demikian, penggunaan LEFT JOIN yang salah dalam contoh ini akan membutuhkan lebih banyak halaman atau sumber daya dari SQL Server. Oleh karena itu, ini akan berjalan lebih lambat.

Bawa pulang

Jika Anda ingin menampilkan baris dalam, gunakan INNER JOIN. Jika tidak, jangan filter tabel kanan di LEFT JOIN dengan nilai bukan nol. Jika ini terjadi, Anda akan mendapatkan kueri yang lebih lambat daripada jika Anda menggunakan INNER JOIN.

KIAT BONUS :Situasi ini juga terjadi dalam RIGHT JOIN ketika tabel kiri difilter dengan nilai bukan nol.

Menggunakan Jenis Gabung yang Tidak Benar dalam Multi-Gabung

Misalkan kita ingin mendapatkan semua vendor dan jumlah pesanan pembelian produk untuk masing-masing. Ini kodenya:

USE AdventureWorks
GO

SELECT
 v.BusinessEntityID
,v.Name AS Vendor
,pod.ProductID
,pod.OrderQty
FROM Purchasing.Vendor v
LEFT JOIN Purchasing.PurchaseOrderHeader poh ON v.BusinessEntityID = poh.VendorID
LEFT JOIN Purchasing.PurchaseOrderDetail pod ON poh.PurchaseOrderID = pod.PurchaseOrderID 

Kode di atas mengembalikan vendor dengan pesanan pembelian dan yang tidak. Gambar 8 menunjukkan Rencana Eksekusi Aktual dari kode di atas.

Berpikir bahwa setiap pesanan pembelian memiliki detail pesanan pembelian yang dijamin, INNER JOIN akan lebih baik. Namun, benarkah demikian?

Pertama, mari kita modifikasi kode dengan INNER JOIN.

USE AdventureWorks
GO

SELECT
 v.BusinessEntityID
,v.Name AS Vendor
,pod.ProductID
,pod.OrderQty
FROM Purchasing.Vendor v
LEFT JOIN Purchasing.PurchaseOrderHeader poh ON v.BusinessEntityID = poh.VendorID
INNER JOIN Purchasing.PurchaseOrderDetail pod ON poh.PurchaseOrderID = pod.PurchaseOrderID 

Ingat, persyaratan di atas mengatakan "semua" vendor. Karena kami menggunakan LEFT JOIN pada kode sebelumnya, kami akan mendapatkan vendor tanpa pengembalian pesanan pembelian. Itu karena PurchaseOrderID null .

Mengubah gabungan menjadi INNER JOIN akan membuang semua PurchaseOrderIDs. nol. Ini juga akan membatalkan semua VendorID null dari Penjual meja. Akibatnya, itu menjadi INNER JOIN.

Apakah itu asumsi yang benar? Rencana Eksekusi akan mengungkapkan jawabannya:

Seperti yang Anda lihat, semua tabel diproses menggunakan INNER JOIN. Oleh karena itu, asumsi kami benar. Tetapi yang terburuk, kumpulan hasil sekarang salah karena vendor tanpa pesanan tidak disertakan.

Bawa pulang

Seperti pada kasus sebelumnya, jika Anda menginginkan INNER JOIN, gunakan itu. Tapi Anda tahu apa yang harus dilakukan jika Anda menghadapi situasi seperti di sini.

Dalam hal ini, INNER JOIN akan membuang semua baris luar hingga tabel teratas dalam hubungan. Bahkan jika Anda bergabung yang lain adalah GABUNG KIRI, itu tidak masalah. Kami telah membuktikannya dalam Rencana Eksekusi.

Penggunaan COUNT() yang Salah di Gabungan Luar

Ingat kode sampel kami yang menghitung jumlah pesanan per tanggal dan hasilnya pada Gambar 6?

Di sini, kami akan mengklarifikasi mengapa 02/03/2014 disorot dan hubungannya dengan COUNT(soh.OrderDate) .

Jika Anda mencoba menggunakan COUNT(*), jumlah pesanan untuk tanggal tersebut menjadi 1, yang salah. Tidak ada pesanan pada tanggal tersebut. Jadi, saat menggunakan COUNT() dengan OUTER JOIN, gunakan kolom yang benar untuk menghitung.

Dalam kasus kami, soh.OrderDate bisa nol atau tidak. Jika bukan nol, COUNT() akan menyertakan baris dalam hitungan. COUNT(*) akan membuatnya menghitung semuanya, termasuk nol. Dan pada akhirnya, hasil yang salah.

Bawa Bawaan OUTER JOIN

Mari kita rangkum poin-poinnya:

  • OUTER JOIN dapat mengembalikan baris dalam dan baris luar. Baris dalam adalah hasil yang mirip dengan hasil INNER JOIN. Baris luar adalah nilai bukan nol dengan pasangan nolnya berdasarkan kondisi gabungan.
  • OUTER JOIN bisa KIRI, KANAN, atau PENUH. Kami memiliki contoh untuk masing-masing.
  • Baris luar yang dikembalikan oleh OUTER JOIN dapat digunakan dalam berbagai cara praktis. Kami punya ide kapan Anda bisa menggunakan barang ini.
  • Kami juga memiliki peringatan dalam menggunakan OUTER JOIN. Perhatikan 3 poin di atas untuk menghindari bug dan masalah performa.

Bagian terakhir dari seri ini akan membahas CROSS JOIN. Jadi, sampai saat itu. Dan jika Anda menyukai postingan ini, bagikan cinta dengan mengklik tombol media sosial. Selamat membuat kode!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bahasa Manipulasi Data SQL

  2. Model Data Bisnis Berlangganan

  3. Nomenklatur &Arsitektur Produk IRI

  4. Pemicu dalam SQL

  5. 10 sumber daya yang berguna bagi mereka yang ingin tahu lebih banyak tentang SQL