0Pricing
Coding Interview Prep · Pelajaran

Menulis Ulang Subkueri Berkorelasi sebagai JOIN

Ubah logika berkorelasi menjadi JOIN atau fungsi jendela demi kinerja.

Menulis Ulang Subkueri Berkorelasi sebagai JOIN adalah pelajaran Coding Interview Prep gratis di CoddyKit. Ini adalah pelajaran 4 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 Coding Interview Prep, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Coding Interview Prep mencakup 4 pelajaran total.

Mengapa Perlu Menulis Ulang

Subkueri berkorelasi mudah dibaca, tetapi dapat lambat: kueri dalam mungkin dijalankan sekali untuk setiap baris luar. Pewawancara sering meminta Anda untuk menulis ulangnya menjadi penggabungan atau fungsi jendela guna meningkatkan performa.

Tujuannya adalah mendapatkan hasil yang sama dengan satu kali melewati data, bukan pemindaian kueri dalam berulang kali.

Mengetahui dua atau tiga pola penulisan ulang, serta kapan masing-masing pola tetap menjaga kebenaran, merupakan keterampilan inti tingkat menengah.

Pola 1: EXISTS menjadi INNER JOIN

EXISTS berkorelasi yang menguji setidaknya satu kecocokan sering kali dapat diubah menjadi INNER JOIN.

Namun, berhati-hatilah: penggabungan dapat menghasilkan baris luar duplikat jika beberapa baris dalam cocok. Tambahkan DISTINCT atau gunakan agregat untuk mengembalikan satu baris per kunci luar.

-- Correlated EXISTS
SELECT c.customer_id, c.name
FROM customers c
WHERE EXISTS (SELECT 1 FROM orders o
             WHERE o.customer_id = c.customer_id);

-- Join rewrite (DISTINCT avoids dupes from fan-out)
SELECT DISTINCT c.customer_id, c.name
FROM customers c
JOIN orders o ON o.customer_id = c.customer_id;

Masalah Penggandaan Baris

Kesalahan penulisan ulang yang paling umum adalah melupakan penggandaan baris. EXISTS mengembalikan setiap pelanggan satu kali, terlepas dari jumlah pesanannya. Penggabungan sederhana mengembalikan satu baris untuk setiap pesanan sehingga jumlahnya menjadi lebih besar dari seharusnya.

Jika langkah berikutnya melakukan COUNT(*) atau SUM(amount) atas hasil penggabungan tersebut tanpa pengelompokan yang cermat, angkanya akan salah.

Selalu tanyakan: apakah penggabungan dapat menggandakan baris? Jika ya, gunakan DISTINCT atau GROUP BY untuk menggabungkannya kembali.

Pola 2: NOT EXISTS menjadi LEFT JOIN / IS NULL

Penulisan ulang untuk mencari baris tanpa pasangan merupakan pola wawancara yang hampir selalu muncul. NOT EXISTS berkorelasi diubah menjadi LEFT JOIN dengan sisi kanan bernilai NULL.

Baris luar yang tidak memiliki pasangan akan mendapatkan NULL di sisi kanan; penyaringan berdasarkan NULL tersebut mempertahankan tepat baris yang tidak memiliki kecocokan.

-- Correlated NOT EXISTS
SELECT c.customer_id FROM customers c
WHERE NOT EXISTS (SELECT 1 FROM orders o
                  WHERE o.customer_id = c.customer_id);

-- LEFT JOIN / IS NULL rewrite
SELECT c.customer_id
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.customer_id
WHERE o.customer_id IS NULL;

Pilih Kolom yang Tidak Bernilai NULL untuk Pengujian

Dalam penulisan ulang LEFT JOIN / IS NULL, uji kolom sisi kanan yang tidak pernah bernilai NULL pada kecocokan nyata, idealnya kunci penggabungan atau kunci utama.

Jika Anda menguji kolom yang dapat bernilai NULL, Anda tidak dapat membedakan ketidakcocokan yang sebenarnya (tidak ada baris) dari baris yang cocok tetapi kebetulan memiliki NULL di kolom tersebut. Kesalahan itu mengembalikan baris yang salah.

Menggunakan kunci penggabungan (di sini o.customer_id) atau o.order_id menjamin bahwa NULL berarti "tidak ada baris yang cocok."

Pola 3: Agregat Skalar menjadi JOIN + GROUP BY

Agregat berkorelasi dalam SELECT dapat diubah menjadi penggabungan dengan subkueri yang dikelompokkan (tabel turunan).

Hitung agregat per kelompok satu kali, lalu gabungkan kembali hasilnya ke baris detail. Kueri dalam dijalankan satu kali, bukan untuk setiap baris.

-- Correlated scalar aggregate
SELECT e1.name,
       (SELECT MAX(e2.salary) FROM employees e2
        WHERE e2.dept_id = e1.dept_id) AS dept_max
FROM employees e1;

-- Join + GROUP BY rewrite
SELECT e.name, m.dept_max
FROM employees e
JOIN (SELECT dept_id, MAX(salary) AS dept_max
      FROM employees GROUP BY dept_id) m
  ON m.dept_id = e.dept_id;

Pola 4: Penulisan Ulang dengan Fungsi Jendela

Sering kali, penulisan ulang yang paling rapi adalah menggunakan fungsi jendela. MAX(salary) OVER (PARTITION BY dept_id) sepenuhnya menggantikan agregat berkorelasi tanpa memerlukan penggabungan.

Fungsi ini menghitung nilai kelompok dalam satu kali melewati data dan mempertahankan setiap baris detail. Biasanya, inilah jawaban yang paling ingin dilihat pewawancara untuk kueri analitik.

SELECT name,
       dept_id,
       salary,
       MAX(salary) OVER (PARTITION BY dept_id) AS dept_max
FROM employees;

Penulisan Ulang N Terbesar per Kelompok

Subkueri berkorelasi yang memilih baris teratas untuk setiap kelompok (salary = MAX per dept) dapat ditulis ulang dengan rapi menggunakan ROW_NUMBER.

Bagi berdasarkan kelompok, urutkan berdasarkan metrik, lalu pertahankan peringkat 1. Gunakan RANK jika Anda ingin mempertahankan semua baris teratas dengan nilai seri.

SELECT name, dept_id, salary
FROM (
    SELECT name, dept_id, salary,
           ROW_NUMBER() OVER (PARTITION BY dept_id
                              ORDER BY salary DESC) AS rn
    FROM employees
) t
WHERE rn = 1;

Kapan Tidak Perlu Menulis Ulang

Menulis ulang tidak selalu memberikan hasil yang lebih baik. Pertahankan subkueri berkorelasi jika:

  • Himpunan luar sangat kecil, sehingga biaya per baris dapat diabaikan.
  • Kolom berkorelasi memiliki indeks yang baik dan pengoptimal sudah mengubahnya menjadi penggabungan semi yang efisien.
  • Keterbacaan lebih penting daripada optimasi kecil dalam kode yang dipelihara.

Pengoptimal modern sering mengubah EXISTS menjadi penggabungan semi secara otomatis. Katakan bahwa Anda akan mengukurnya dengan EXPLAIN sebelum menganggap penulisan ulang akan membantu.

Memverifikasi Kesetaraan

Setelah penulisan ulang apa pun, pastikan hasilnya mengembalikan baris dan kardinalitas yang sama seperti versi asli.

  • Periksa apakah jumlah barisnya sama.
  • Periksa apakah penggandaan baris akibat penggabungan tidak menghasilkan duplikat.
  • Periksa apakah kasus tepi berupa NULL dan kelompok kosong masih berperilaku dengan benar.

Cara cepat: jalankan kedua versi lalu bandingkan dengan EXCEPT ke kedua arah; hasil kosong berarti keduanya sama. Pewawancara menghargai verifikasi, bukan asumsi.

SELECT customer_id FROM query_a
EXCEPT
SELECT customer_id FROM query_b;
-- and the reverse; both empty => equivalent

Menulis Ulang IN menjadi JOIN

Subkueri IN yang tidak berkorelasi sering kali juga dapat diubah menjadi penggabungan, tetapi peringatan tentang penggandaan baris tetap berlaku. IN menghapus duplikat keanggotaan, sedangkan penggabungan tidak.

Jika daftar dalam memiliki kunci duplikat, penggabungan akan mengulang baris luar. Gunakan DISTINCT pada sisi dalam atau hasil akhir agar sesuai dengan semantik IN.

-- IN subquery
SELECT c.name FROM customers c
WHERE c.customer_id IN (SELECT o.customer_id FROM orders o);

-- Join rewrite, de-duplicated to match IN
SELECT DISTINCT c.name
FROM customers c
JOIN orders o ON o.customer_id = c.customer_id;

Pemeriksaan Singkat

Pilih penulisan ulang penggabungan yang benar untuk pencarian tanpa pasangan dengan NOT EXISTS berkorelasi.

Ringkasan: Menulis Ulang Subkueri Berkorelasi menjadi Penggabungan

Hal-hal penting:

  • EXISTS → INNER JOIN (tambahkan DISTINCT untuk menghindari duplikat akibat penggandaan baris).
  • NOT EXISTS → LEFT JOIN ... WHERE key IS NULL (uji kolom yang tidak dapat bernilai NULL).
  • Agregat skalar berkorelasi → lakukan JOIN dengan tabel turunan yang dikelompokkan, atau lebih baik, gunakan fungsi jendela.
  • Baris teratas per kelompok → ROW_NUMBER (atau RANK untuk nilai seri).
  • Verifikasi kesetaraan dan periksa dengan EXPLAIN sebelum menganggap penulisan ulang lebih cepat.

Memahami kedua bentuk dan jebakan penggandaan baris merupakan hal yang tepat untuk diuji dalam wawancara tingkat menengah.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Menulis Ulang Subkueri Berkorelasi sebagai JOIN” gratis?

Ya — teks lengkap “Menulis Ulang Subkueri Berkorelasi sebagai JOIN” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Coding Interview Prep, upgrade ke CoddyKit PRO. Kursus Coding Interview Prep mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Menulis Ulang Subkueri Berkorelasi sebagai JOIN”?

Ubah logika berkorelasi menjadi JOIN atau fungsi jendela demi kinerja. Kamu berlatih Coding 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 Coding Interview Prep?

Tidak diperlukan pengalaman sebelumnya. Coding 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 4 dari 4.

Berapa lama pelajaran “Menulis Ulang Subkueri Berkorelasi sebagai JOIN” 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 Coding Interview Prep ini?

Ya. Setiap pelajaran Coding 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. Anatomi Subkueri Berkorelasi
  2. Agregat Per Grup Tanpa GROUP BY
  3. EXISTS dan NOT EXISTS Berkorelasi
  4. Menulis Ulang Subkueri Berkorelasi sebagai JOIN
← Kembali ke Coding Interview Prep