0Pricing
SQL Interview Prep · Pelajaran

Fan-Out JOIN dan Penggandaan Baris

Mengapa JOIN dapat mengembalikan lebih banyak baris daripada salah satu tabel dan bagaimana pewawancara mengujinya.

Fan-Out JOIN dan Penggandaan Baris adalah pelajaran SQL Interview Prep gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar SQL Interview Prep, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus SQL Interview Prep mencakup 4 pelajaran total.

Saat JOIN Mengembalikan Terlalu Banyak Baris

Salah satu pertanyaan wawancara yang paling mengungkap terdengar sederhana: "dapatkah JOIN mengembalikan lebih banyak baris daripada tabel yang lebih besar?" Jawabannya ya, dan fenomena ini disebut penggandaan atau perkalian baris.

Kandidat yang mengatakan "JOIN hanya menggabungkan tabel" tidak menyadari hal ini. Kandidat yang dapat memperkirakan jumlah baris secara tepat akan lebih mudah diterima bekerja. Pelajaran ini membangun kemampuan memperkirakan tersebut.

Penyebabnya: Pencocokan Satu-ke-Banyak

Penggandaan terjadi ketika satu baris di kiri cocok dengan banyak baris di kanan. Setiap kecocokan menghasilkan baris keluaran tersendiri.

Dengan pelanggan dan pesanan, Ada (satu pelanggan) memiliki dua pesanan. JOIN menghasilkan satu baris per pesanan, sehingga Ada muncul dua kali. Kolom pelanggan berulang, sedangkan hanya kolom pesanan yang berbeda.

SELECT c.name, o.amount
FROM customers c
JOIN orders o ON o.customer_id = c.id;
-- Ada appears twice (she has 2 orders)
-- name | amount
-- Ada  | 50
-- Ada  | 20
-- Bob  | 99

Menghitung Baris Keluaran

Jumlah baris keluaran sama dengan total kecocokan per baris kiri, bukan jumlah pelanggan.

  • Ada -> 2 pesanan -> 2 baris
  • Bob -> 1 pesanan -> 1 baris
  • Cleo -> 0 pesanan -> 0 baris (dihapus oleh INNER JOIN)

Total = 3 baris, meskipun tabel pelanggan juga memiliki 3 baris. Jika Ada memiliki 10 pesanan, hasilnya melonjak menjadi 11 baris.

Relasi Banyak-ke-Banyak Membengkak

Penggandaan menjadi berlipat ganda ketika kedua sisi memiliki banyak kecocokan untuk kunci yang sama. Jika kunci K muncul 3 kali di kiri dan 4 kali di kanan, JOIN menghasilkan 3 x 4 = 12 baris untuk kunci tersebut.

Inilah cara JOIN yang tampak kecil membengkak menjadi jutaan baris. Pewawancara senang memberikan kunci duplikat di kedua sisi untuk melihat apakah Anda menyadari perkalian tersebut.

-- left has 3 rows with tag 'A', right has 4 rows with tag 'A'
SELECT l.id, r.id
FROM left_t l
JOIN right_t r ON r.tag = l.tag;
-- tag 'A' alone yields 3 * 4 = 12 output rows

Jebakan Agregasi

Inilah kesalahan yang paling sering sengaja dibuat oleh pewawancara. Anda menggabungkan pesanan dengan item pesanan untuk mendapatkan detail item, lalu menggunakan SUM pada nilai pesanan. Karena setiap pesanan menghasilkan beberapa baris item, nilai pesanan dihitung satu kali untuk setiap item.

SUM kini menjadi sangat besar secara keliru. Kuerinya terlihat benar dan bahkan berhasil dijalankan, sehingga kesalahan ini berbahaya.

-- BUG: order.amount duplicated across items
SELECT SUM(o.amount) AS total
FROM orders o
JOIN order_items i ON i.order_id = o.id;
-- a 3-item order counts o.amount 3 times

Melihat Pembengkakan

Misalkan satu pesanan memiliki nilai 100 dan tiga item. JOIN menghasilkan tiga baris, masing-masing membawa nilai 100. SUM(o.amount) mengembalikan 300, bukan 100.

Perbaikannya adalah melakukan agregasi pada tingkat rincian yang tepat: jumlahkan item, atau jumlahkan pesanan yang berbeda secara terpisah. Jangan pernah menggunakan SUM pada nilai induk di seluruh JOIN anak yang mengalami penggandaan.

o.id | o.amount | i.id
7    | 100      | 71
7    | 100      | 72
7    | 100      | 73
-- SUM(o.amount) = 300  (WRONG, should be 100)

Perbaikan 1: Agregasikan Anak Terlebih Dahulu

Perbaikan yang paling bersih adalah melakukan agregasi awal pada sisi yang memiliki banyak baris dalam subkueri atau CTE, sehingga setiap induk cocok tepat dengan satu baris ringkasan. Tidak ada penggandaan dan tidak ada pembengkakan nilai.

Di sini, item diringkas menjadi satu baris per pesanan sebelum JOIN dilakukan, sehingga nilai induk tidak pernah diduplikasi.

SELECT o.id, o.amount, i.item_count
FROM orders o
JOIN (
  SELECT order_id, COUNT(*) AS item_count
  FROM order_items
  GROUP BY order_id
) i ON i.order_id = o.id;

Perbaikan 2: COUNT(DISTINCT) dan Penjumlahan Bersyarat

Jika Anda harus melakukan agregasi setelah JOIN yang menggandakan baris, hitung atau jumlahkan pada tingkat rincian yang tepat. Gunakan COUNT(DISTINCT o.id) untuk menghitung pesanan, bukan baris item.

Perhatikan: SUM(DISTINCT o.amount) bukan perbaikan yang aman, karena dua pesanan berbeda dapat secara sah memiliki jumlah yang sama dan akan digabungkan. Agregasi awal lebih dapat diandalkan.

SELECT COUNT(DISTINCT o.id)   AS num_orders,
       COUNT(i.id)            AS num_items
FROM orders o
JOIN order_items i ON i.order_id = o.id;

Mendeteksi Penggandaan Sebelum Menjadi Masalah

Diagnosis singkat yang disukai pewawancara: periksa apakah kunci JOIN bersifat unik pada sisi yang Anda perkirakan sebagai sisi "satu". Jika jumlah kunci unik lebih sedikit daripada jumlah baris, sisi tersebut memiliki duplikat dan akan mengalami penggandaan.

-- if this returns rows, order_id is NOT unique in order_items
SELECT order_id, COUNT(*) AS n
FROM order_items
GROUP BY order_id
HAVING COUNT(*) > 1;

Memverifikasi Tingkat Rincian dengan Penghitungan

Sebelum mempercayai agregat apa pun atas hasil JOIN, periksa kewajaran jumlah baris. Cara cepatnya adalah membandingkan jumlah hasil JOIN dengan jumlah baris pada tabel yang Anda harapkan menjadi tingkat rinciannya.

Jika COUNT(*) pada JOIN lebih besar daripada COUNT(*) pada tabel pesanan, JOIN tersebut mengalami penggandaan dan agregat per pesanan apa pun berisiko. Pemeriksaan satu baris ini telah menyelamatkan banyak jawaban wawancara.

-- joined rows should equal order count if no fan-out
SELECT COUNT(*) AS joined_rows
FROM orders o
JOIN order_items i ON i.order_id = o.id;

SELECT COUNT(*) AS order_rows FROM orders;
-- joined_rows > order_rows  =>  fan-out present

Penggandaan Tidak Selalu Merupakan Kesalahan

Terkadang Anda memang menginginkan satu baris per anak. Menampilkan setiap item pesanan bersama informasi utama pesanannya merupakan penggandaan yang benar. Keterampilannya adalah mengetahui tingkat rincian sasaran Anda: berapa banyak baris yang harus dihasilkan oleh satu entitas?

Tentukan tingkat rincian sebelum menulis kueri. "Saya ingin satu baris per item pesanan" dibandingkan dengan "satu baris per pesanan" menentukan apakah penggandaan merupakan fitur atau kesalahan.

Pemeriksaan Singkat

Perkirakan keluaran JOIN satu-ke-banyak.

Ringkasan: Penggandaan dan Perkalian Baris

Hal yang perlu diingat:

  • JOIN menghasilkan satu baris untuk setiap pasangan yang cocok, sehingga pencocokan satu-ke-banyak menduplikasi sisi yang "satu".
  • Kunci banyak-ke-banyak mengalami perkalian: 3 x 4 = 12 baris untuk kunci tersebut.
  • Melakukan agregasi atas nilai induk di seluruh JOIN yang mengalami penggandaan membengkakkan total dan hitungan.
  • Perbaiki dengan melakukan agregasi awal pada anak, atau dengan menghitung/menjumlahkan pada tingkat rincian yang benar, misalnya COUNT(DISTINCT).
  • Selalu nyatakan tingkat rincian yang diinginkan terlebih dahulu; penggandaan hanya merupakan kesalahan jika melanggar tingkat tersebut.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Fan-Out JOIN dan Penggandaan Baris” gratis?

Ya — teks lengkap “Fan-Out JOIN dan Penggandaan Baris” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus SQL Interview Prep, upgrade ke CoddyKit PRO. Kursus SQL Interview Prep mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Fan-Out JOIN dan Penggandaan Baris”?

Mengapa JOIN dapat mengembalikan lebih banyak baris daripada salah satu tabel dan bagaimana pewawancara mengujinya. Kamu berlatih SQL Interview Prep dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai SQL Interview Prep?

Tidak diperlukan pengalaman sebelumnya. SQL Interview Prep di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.

Berapa lama pelajaran “Fan-Out JOIN dan Penggandaan Baris” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran SQL Interview Prep ini?

Ya. Setiap pelajaran SQL Interview Prep menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Cara INNER JOIN Mencocokkan Baris
  2. ON vs WHERE dalam JOIN
  3. Fan-Out JOIN dan Penggandaan Baris
  4. Menggabungkan Tiga Tabel atau Lebih
← Kembali ke SQL Interview Prep