- 1 1. Pendahuluan
- 2 2. Dasar-dasar Klausa WITH (Common Table Expressions)
- 3 3. Penggunaan Dasar Klausa WITH MySQL
- 4 4. Contoh Praktis dari Klausa WITH Rekursif
- 5 5. Catatan dan Pertimbangan Saat Menggunakan Klausa WITH
- 6 6. Kasus Penggunaan Praktis dalam Skenario Dunia Nyata
- 7 7. FAQ (Pertanyaan yang Sering Diajukan)
- 7.1 Q1: Kapan saya harus menggunakan klausa WITH?
- 7.2 Q2: Kapan CTE rekursif berguna?
- 7.3 Q3: Apakah kueri yang menggunakan klausa WITH lebih efisien daripada view?
- 7.4 Q4: Apa yang menyebabkan penurunan kinerja saat menggunakan klausa WITH?
- 7.5 Q5: Alternatif apa yang ada untuk versi MySQL yang tidak mendukung klausa WITH?
- 7.6 Q6: Praktik terbaik apa yang harus diikuti saat menggunakan klausa WITH?
- 8 8. Conclusion
1. Pendahuluan
MySQL adalah sistem manajemen basis data yang banyak digunakan oleh pengembang dan administrator basis data, menyediakan fungsionalitas SQL yang kuat dan fleksibel. Di antara fiturnya, klausa WITH (Common Table Expression: CTE), yang diperkenalkan pada MySQL 8.0, adalah alat yang kuat yang membuat kueri SQL lebih mudah dibaca dan meningkatkan kemampuan pemeliharaan.
Artikel ini menjelaskan klausa WITH mulai dari dasar hingga penggunaan lanjutan, ditujukan untuk pemula hingga pengguna menengah. Secara khusus, kami membahas topik praktis seperti mengganti subkueri dan menerapkan kueri rekursif.
Bagi mereka yang belajar SQL atau kesulitan mengoptimalkan kueri dalam pekerjaan sehari-hari, artikel ini bertujuan memberikan solusi konkret. Ikuti konten di bawah ini untuk memahami dasar-dasar klausa WITH dan menerapkannya dalam skenario dunia nyata.
2. Dasar-dasar Klausa WITH (Common Table Expressions)
Apa Itu Klausa WITH?
Klausa WITH adalah sintaks yang digunakan untuk mendefinisikan set hasil sementara (Common Table Expression, CTE) dalam sebuah kueri SQL dan merujuknya dalam kueri berikutnya. Didukung sejak MySQL 8.0, klausa ini memungkinkan subkueri yang kompleks ditulis ulang dalam bentuk yang lebih jelas dan ringkas.
Sebagai contoh, ketika menulis subkueri secara langsung, keterbacaan dapat menurun dan kueri secara keseluruhan menjadi panjang. Dengan menggunakan klausa WITH, Anda dapat membagi kueri menjadi blok logis, sehingga lebih mudah dipahami.
Sintaks Dasar Klausa WITH
Berikut adalah sintaks dasar klausa WITH:
WITH table_name AS (
SELECT column1, column2
FROM original_table
WHERE condition
)
SELECT column1, column2
FROM table_name;
Dalam sintaks ini, sebuah tabel virtual (Common Table Expression) didefinisikan setelah WITH, dan kemudian digunakan dalam kueri utama. Hal ini membuat subkueri yang sering digunakan dapat diekspresikan secara ringkas.
Perbedaan dengan Subkueri dan View
Klausa WITH membuat set hasil yang tersedia sementara dan berbeda dari subkueri serta view dalam beberapa aspek.
| Feature | WITH Clause | Subquery | View |
|---|---|---|---|
| Scope | Valid only within the query | Usable only where defined | Reusable across the entire database |
| Persistence | Temporary | Temporary | Permanent |
| Purpose | Simplifies complex queries | Temporary data extraction | Frequently reused data extraction |
Klausa WITH lebih mudah dibaca dibandingkan subkueri dan ideal ketika Anda tidak perlu membuat objek permanen seperti view.
Manfaat Menggunakan Klausa WITH
- Meningkatkan Keterbacaan Kueri Bahkan ketika terdapat banyak subkueri, mengorganisirnya dengan klausa WITH memperjelas struktur.
- Meningkatkan Dapat Digunakan Kembali Dengan mendefinisikan set hasil sementara, set tersebut dapat dirujuk berkali‑kali dalam kueri.
- Meningkatkan Kemudahan Pemeliharaan Karena kueri dapat dibagi secara logis, modifikasi dan ekstensi menjadi lebih mudah.
3. Penggunaan Dasar Klausa WITH MySQL
Mengganti Subkueri
Klausa WITH adalah alat yang kuat untuk menyederhanakan subkueri yang kompleks. Menyematkan subkueri secara langsung dapat membuat seluruh kueri menjadi rumit dan sulit dibaca, tetapi dengan menggunakan klausa WITH keterbacaan meningkat.
Berikut adalah contoh dasar mengganti subkueri menggunakan klausa WITH.
Menggunakan Subkueri:
SELECT AVG(sales.total) AS average_sales
FROM (
SELECT SUM(amount) AS total
FROM orders
GROUP BY customer_id
) AS sales;
Menggunakan Klausa WITH:
WITH sales AS (
SELECT SUM(amount) AS total
FROM orders
GROUP BY customer_id
)
SELECT AVG(sales.total) AS average_sales
FROM sales;
Dalam contoh ini, set hasil sementara bernama sales didefinisikan menggunakan klausa WITH dan kemudian dirujuk dalam kueri utama. Hal ini membuat seluruh kueri lebih mudah dipahami dan lebih terorganisir.
Mendefinisikan Beberapa Common Table Expressions (CTE)
Klausa WITH memungkinkan mendefinisikan beberapa CTE. Ini memungkinkan modularisasi lebih lanjut dari kueri yang kompleks.
Contoh:
WITH
sales_per_customer AS (
SELECT customer_id, SUM(amount) AS total_sales
FROM orders
GROUP BY customer_id
),
high_value_customers AS (
SELECT customer_id
FROM sales_per_customer
WHERE total_sales > 10000
)
SELECT customer_id
FROM high_value_customers;
Dalam contoh ini, sales_per_customer menghitung total penjualan per pelanggan, dan berdasarkan hasil tersebut, high_value_customers mengekstrak pelanggan dengan jumlah pembelian tinggi. Dengan menggunakan beberapa CTE secara berurutan, kueri dapat dibangun langkah demi langkah.
Menggunakan CTE Bersarang
Dengan menggunakan CTE bersarang, Anda dapat melakukan operasi data yang lebih kompleks.
Contoh:
WITH
sales_data AS (
SELECT product_id, SUM(amount) AS total_sales
FROM orders
GROUP BY product_id
),
ranked_sales AS (
SELECT product_id, total_sales,
RANK() OVER (ORDER BY total_sales DESC) AS rank
FROM sales_data
)
SELECT product_id, total_sales
FROM ranked_sales
WHERE rank <= 5;
Dalam kueri ini, sales_data mengagregasi penjualan per produk, dan ranked_sales memberikan peringkat berdasarkan volume penjualan. Akhirnya, lima produk teratas diekstrak.
Poin Penting untuk Penggunaan Praktis
- Berpikir dalam Langkah Logis Bangun CTE langkah demi langkah untuk meningkatkan keterbacaan dan mempermudah debugging.
- Simpan Hasil Perhitungan Menengah Kelompokkan hasil perhitungan atau kondisi penyaringan yang digunakan berulang kali ke dalam CTE untuk mengurangi duplikasi kode.
- Berhati-hatilah dengan Dataset Besar Karena CTE menghasilkan set hasil sementara, pertimbangkan dampak kinerja saat bekerja dengan data dalam jumlah besar.
4. Contoh Praktis dari Klausa WITH Rekursif
Apa Itu Klausa WITH Rekursif?
Klausa WITH rekursif (CTE rekursif) adalah metode yang menggunakan Common Table Expression untuk secara berulang mengeksekusi kueri yang merujuk pada dirinya sendiri, memungkinkan Anda memproses data hierarkis dan perhitungan iteratif. CTE rekursif didukung di MySQL 8.0 dan versi selanjutnya serta sangat berguna saat bekerja dengan hubungan orang tua‑anak dan struktur hierarkis.
Sintaks Dasar CTE Rekursif
Untuk mendefinisikan CTE rekursif, gunakan kata kunci WITH RECURSIVE. Sintaks dasar adalah sebagai berikut:
WITH RECURSIVE recursive_table_name AS (
initial_query -- starting point of the recursion
UNION ALL
recursive_query -- query called recursively
)
SELECT * FROM recursive_table_name;
- Kueri awal : Mengambil dataset pertama untuk proses rekursif.
- Kueri rekursif : Menghasilkan baris baru berdasarkan kueri awal atau hasil iterasi sebelumnya.
- UNION ALL : Menggabungkan hasil kueri awal dan kueri rekursif.
Contoh: Memproses Data Hierarkis
CTE rekursif sering digunakan untuk memperluas data dengan struktur hierarkis (mis., pohon organisasi atau pohon kategori).
Contoh: Memperluas hierarki manajemen karyawan
Pertimbangkan tabel employees berikut:
| employee_id | name | manager_id |
|---|---|---|
| 1 | Alice | NULL |
| 2 | Bob | 1 |
| 3 | Charlie | 1 |
| 4 | David | 2 |
Dengan data ini, kita dapat membuat kueri yang mengambil hierarki lengkap mulai dari seorang karyawan tertentu.
WITH RECURSIVE employee_hierarchy AS (
-- Initial query: get top-level employees
SELECT employee_id, name, manager_id, 1 AS level
FROM employees
WHERE manager_id IS NULL
UNION ALL
-- Recursive query: get direct reports
SELECT e.employee_id, e.name, e.manager_id, eh.level + 1
FROM employees e
INNER JOIN employee_hierarchy eh
ON e.manager_id = eh.employee_id
)
SELECT * FROM employee_hierarchy;
Hasil:
| employee_id | name | manager_id | level |
|---|---|---|---|
| 1 | Alice | NULL | 1 |
| 2 | Bob | 1 | 2 |
| 3 | Charlie | 1 | 2 |
| 4 | David | 2 | 3 |
Dalam kueri ini, bawahan dicari secara rekursif berdasarkan manager_id, memperluas hierarki lengkap.
Batasan dan Peringatan untuk CTE Rekursif
- Kondisi Akhir Diperlukan Jika kueri rekursif tidak memenuhi kondisi akhir, loop tak terbatas dapat terjadi. Selalu sertakan kondisi yang tepat untuk mencegah rekursi tak terbatas.
- Dampak Kinerja CTE rekursif dapat melibatkan banyak perhitungan pada dataset besar, yang dapat meningkatkan waktu eksekusi. Gunakan klausa
LIMITdan kondisi penyaringan untuk meningkatkan efisiensi. - Batas Kedalaman Rekursi MySQL memiliki batas pada kedalaman rekursi, jadi berhati-hatilah saat menjalankan proses rekursif yang sangat dalam. Batas ini dapat dikonfigurasi dengan parameter
max_recursive_iterations.
Skenario Di Mana CTE Rekursif Berguna
- Menelusuri struktur folder : Mencari folder dan subfolder secara rekursif.
- Membangun bagan organisasi : Memvisualisasikan hierarki dari manajer hingga bawahan.
- Menampilkan pohon kategori : Mengambil kategori produk hierarkis atau struktur tag.
CTE rekursif adalah cara yang kuat untuk menulis kueri SQL yang ringkas untuk skenario ini sekaligus meningkatkan keterbacaan.
5. Catatan dan Pertimbangan Saat Menggunakan Klausa WITH
Dampak Kinerja dan Optimasi
- Rekalkulasi CTE Secara umum, CTE yang didefinisikan dengan klausa WITH dihitung ulang setiap kali direferensikan. Oleh karena itu, menggunakan CTE yang sama beberapa kali dapat meningkatkan waktu eksekusi kueri. Contoh:
WITH sales AS ( SELECT product_id, SUM(amount) AS total_sales FROM orders GROUP BY product_id ) SELECT * FROM sales WHERE total_sales > 1000; SELECT COUNT(*) FROM sales;
Dalam kasus di atas, sales direferensikan dua kali, sehingga dihitung dua kali. Untuk menghindari hal ini, ketika Anda perlu mereferensikan hasil beberapa kali, menyimpan hasil dalam tabel sementara dapat efektif.
Solusi:
CREATE TEMPORARY TABLE temp_sales AS
SELECT product_id, SUM(amount) AS total_sales
FROM orders
GROUP BY product_id;
SELECT * FROM temp_sales WHERE total_sales > 1000;
SELECT COUNT(*) FROM temp_sales;
- Membagi CTE Kompleks Jika klausa WITH menjadi terlalu dalam bersarang, kueri secara keseluruhan dapat menjadi kompleks dan lebih sulit untuk debug. Penting untuk membagi logika secara tepat sehingga pemrosesan dalam satu CTE tidak menjadi terlalu rumit.
Menggunakan Klausa WITH pada Dataset Besar
Klausa WITH menghasilkan dataset sementara selama eksekusi. Saat menangani sejumlah besar data, hal ini dapat membebani memori atau penyimpanan.
Tindakan Pencegahan:
- Filter Data dengan Klausa WHERE Kurangi perhitungan dengan menyaring data yang tidak diperlukan di dalam CTE.
WITH filtered_orders AS ( SELECT * FROM orders WHERE order_date > '2023-01-01' ) SELECT customer_id, SUM(amount) FROM filtered_orders GROUP BY customer_id;
- Gunakan Klausa LIMIT Jika dataset besar, gunakan
LIMITuntuk mengekstrak hanya data yang Anda butuhkan.
Kompatibilitas Versi MySQL
Klausa WITH di MySQL didukung pada MySQL 8.0 ke atas. Karena versi sebelumnya tidak mendukung klausa WITH, Anda perlu mempertimbangkan alternatif.
Alternatif:
- Gunakan Subquery Gunakan subquery secara langsung alih-alih klausa WITH.
SELECT AVG(total_sales) FROM ( SELECT customer_id, SUM(amount) AS total_sales FROM orders GROUP BY customer_id ) AS sales;
- Buat View Jika Anda membutuhkan kueri yang dapat digunakan kembali, menggunakan view dapat efektif.
CREATE VIEW sales_view AS SELECT customer_id, SUM(amount) AS total_sales FROM orders GROUP BY customer_id; SELECT AVG(total_sales) FROM sales_view;
Cara Menggunakan Klausa WITH dengan Benar
- Prioritaskan Keterbacaan Tujuan klausa WITH adalah untuk mengatur kueri dan meningkatkan keterbacaan. Penggunaan berlebihan dapat membuat kueri lebih kompleks, jadi gunakan hanya bila diperlukan.
- Verifikasi Kinerja Periksa rencana eksekusi (perintah
EXPLAIN) dan pertimbangkan cara mengoptimalkan kinerja.EXPLAIN WITH sales AS ( SELECT product_id, SUM(amount) AS total_sales FROM orders GROUP BY product_id ) SELECT * FROM sales WHERE total_sales > 1000;
6. Kasus Penggunaan Praktis dalam Skenario Dunia Nyata
Mengagregasi Data Penjualan
Berikut contoh mengagregasi data penjualan per bulan dan kemudian menggunakan hasil tersebut untuk menghitung rata-rata penjualan bulanan.
Contoh: Mengagregasi Penjualan Bulanan dan Menghitung Rata-rata
WITH monthly_sales AS (
SELECT
DATE_FORMAT(order_date, '%Y-%m') AS sales_month,
SUM(amount) AS total_sales
FROM orders
GROUP BY sales_month
)
SELECT
sales_month,
total_sales,
AVG(total_sales) OVER () AS average_sales
FROM monthly_sales;
Dalam kueri ini, monthly_sales menghitung penjualan per bulan, dan berdasarkan hasil tersebut, rata‑rata penjualan keseluruhan dihitung. Ini memungkinkan data diatur dengan jelas dan menyederhanakan analisis.
Menyaring Data Berdasarkan Kondisi Spesifik
Dengan memisahkan logika penyaringan yang kompleks ke dalam klausa WITH, keterbacaan dapat ditingkatkan.
Contoh: Membuat Daftar Pelanggan yang Menghabiskan Banyak
WITH customer_totals AS (
SELECT
customer_id,
SUM(amount) AS total_spent
FROM orders
GROUP BY customer_id
)
SELECT
customer_id,
total_spent
FROM customer_totals
WHERE total_spent > 100000;
Dalam kueri ini, customer_totals menghitung total jumlah pembelian per pelanggan, dan pelanggan yang memenuhi kondisi yang ditentukan diekstrak.
Menganalisis Data Hierarkis
Saat menganalisis data hierarkis seperti struktur organisasi atau kategori, klausa WITH rekursif sangat berguna.
Contoh: Mengambil Daftar Bawahan Langsung dan Tidak Langsung
WITH RECURSIVE employee_hierarchy AS (
SELECT
employee_id,
name,
manager_id,
1 AS level
FROM employees
WHERE manager_id IS NULL
UNION ALL
SELECT
e.employee_id,
e.name,
e.manager_id,
eh.level + 1
FROM employees e
INNER JOIN employee_hierarchy eh
ON e.manager_id = eh.employee_id
)
SELECT
employee_id,
name,
manager_id,
level
FROM employee_hierarchy
ORDER BY level, manager_id;
Kueri ini membangun data hierarkis dalam employee_hierarchy dan mengambil karyawan yang dikelompokkan berdasarkan level. Ini memungkinkan pembuatan dinamis informasi mirip bagan organisasi.
Analisis Lanjutan Menggunakan Beberapa CTE
Dengan memanfaatkan beberapa klausa WITH, data dapat diproses langkah demi langkah, membuat analisis kompleks menjadi lebih sederhana.
Contoh: Mengekstrak Produk Terlaris per Kategori
WITH category_sales AS (
SELECT
category_id,
product_id,
SUM(amount) AS total_sales
FROM orders
GROUP BY category_id, product_id
),
ranked_sales AS (
SELECT
category_id,
product_id,
total_sales,
RANK() OVER (PARTITION BY category_id ORDER BY total_sales DESC) AS rank
FROM category_sales
)
SELECT
category_id,
product_id,
total_sales
FROM ranked_sales
WHERE rank <= 3;
Dalam kueri ini, penjualan per kategori dihitung, dan tiga produk teratas dalam setiap kategori diekstrak. Pendekatan ini efektif saat mempersempit data berdasarkan kondisi spesifik.
Poin-Poin Penting untuk Penerapan Praktis
- Rancang Kueri dalam Tahapan Logis Gunakan klausa WITH untuk membagi kueri dan memproses data langkah demi langkah sambil mempertahankan keterbacaan.
- Ekstrak Hanya Data yang Diperlukan Gunakan klausa WHERE dan LIMIT untuk menghindari pemrosesan data yang tidak diperlukan dan merancang kueri yang efisien.
- Aplikasi Bisnis yang Fleksibel Klausa WITH dapat diterapkan secara fleksibel pada analisis penjualan, segmentasi pelanggan, manajemen inventaris, dan lain-lain.

7. FAQ (Pertanyaan yang Sering Diajukan)
Q1: Kapan saya harus menggunakan klausa WITH?
A1:
Klausa WITH sangat efektif dalam skenario berikut:
- Saat Anda ingin menyederhanakan subkueri yang kompleks.
- Saat Anda perlu menggunakan kembali dataset yang sama beberapa kali dalam satu kueri.
- Saat Anda ingin membagi kueri secara logis untuk meningkatkan keterbacaan.
Sebagai contoh, dalam kueri yang menggunakan hasil agregasi yang sama beberapa kali, klausa WITH memungkinkan organisasi yang lebih efisien.
Q2: Kapan CTE rekursif berguna?
A2:
CTE rekursif berguna saat menangani struktur hierarkis atau perhitungan iteratif. Secara khusus:
- Memproses data hierarkis (mis., pohon organisasi, struktur kategori).
- Menampilkan hierarki folder atau file.
- Perhitungan berurutan angka atau periode waktu (mis., menghitung deret Fibonacci).
Menggunakan CTE rekursif memudahkan memperluas dan memproses data yang merujuk pada dirinya sendiri.
Q3: Apakah kueri yang menggunakan klausa WITH lebih efisien daripada view?
A3:
Tergantung pada kasus penggunaannya.
- WITH clause : Membuat set hasil sementara yang hanya digunakan dalam kueri. Cocok untuk data yang tidak perlu sering digunakan kembali.
- View : Disimpan secara permanen di basis data dan dapat digunakan kembali oleh kueri lain. Cocok untuk kueri yang sering digunakan berulang kali.
Memilih metode yang tepat tergantung pada skenario sangat penting.
Q4: Apa yang menyebabkan penurunan kinerja saat menggunakan klausa WITH?
A4:
Penyebab utama penurunan kinerja saat menggunakan klausa WITH meliputi:
- CTE recalculation : Hasil dihitung ulang setiap kali direferensikan, meningkatkan waktu pemrosesan.
- Handling large datasets : Membuat dataset besar dalam CTE meningkatkan penggunaan memori dan mengurangi kinerja.
- Lack of proper indexing : Jika kueri di dalam CTE tidak menggunakan indeks yang tepat, kinerja dapat melambat.
Countermeasures:
- Pertimbangkan tabel sementara atau view jika frekuensi penggunaan kembali tinggi.
- Gunakan klausa WHERE dan LIMIT untuk mempersempit data secara tepat.
Q5: Alternatif apa yang ada untuk versi MySQL yang tidak mendukung klausa WITH?
A5:
Pada versi sebelum MySQL 8.0, klausa WITH tidak didukung, jadi gunakan alternatif berikut:
- Use Subqueries Gunakan subkueri secara langsung alih-alih klausa WITH.
SELECT AVG(total_sales) FROM ( SELECT customer_id, SUM(amount) AS total_sales FROM orders GROUP BY customer_id ) AS sales;
- Use Temporary Tables Simpan dataset yang dapat digunakan kembali dalam tabel sementara.
CREATE TEMPORARY TABLE temp_sales AS SELECT customer_id, SUM(amount) AS total_sales FROM orders GROUP BY customer_id; SELECT AVG(total_sales) FROM temp_sales;
Q6: Praktik terbaik apa yang harus diikuti saat menggunakan klausa WITH?
A6:
Ingatlah praktik terbaik berikut:
- Prioritize simplicity : Jangan memaksa logika kompleks ke dalam satu klausa WITH. Bagi secara tepat.
- Verify performance : Periksa rencana eksekusi menggunakan perintah
EXPLAINdan optimalkan bila perlu. - Consider reusability : Jika frekuensi penggunaan kembali tinggi, manfaatkan view atau tabel sementara.
8. Conclusion
Artikel ini membahas klausa WITH (Common Table Expression, CTE) yang diperkenalkan di MySQL 8.0, mulai dari dasar hingga aplikasi lanjutan. Klausa WITH adalah fitur yang sangat berguna untuk membuat kueri kompleks menjadi ringkas dan mudah dibaca. Berikut adalah poin-poin pentingnya.
Main Benefits of the WITH Clause
- Improved Query Readability Mengatur subkueri yang kompleks, meningkatkan keterbacaan dan pemeliharaan kode SQL.
- Query Reusability Memproses data secara efisien saat merujuk dataset yang sama berkali-kali.
- Enables Recursive Data Operations CTE rekursif menyederhanakan pemrosesan data hierarkis dan perhitungan iteratif.
Practical Usage Points
- Berguna untuk analisis data penjualan dan pelanggan, memungkinkan agregasi langkah demi langkah.
- CTE rekursif efektif untuk pemrosesan data hierarkis (seperti bagan organisasi atau struktur kategori).
- Menggabungkan klausa WITH dengan view atau tabel sementara memungkinkan operasi basis data yang fleksibel dan efisien.
Important Considerations
- Klausa WITH kuat, tetapi penggunaan yang tidak tepat dapat mengurangi kinerja.
- Evaluasi penggunaan kembali dan kinerja kasus per kasus, dan pilih antara view atau tabel sementara bila sesuai.
- Selalu verifikasi efisiensi kueri menggunakan rencana eksekusi (perintah
EXPLAIN).
Next Steps
Dengan menggunakan klausa WITH, Anda dapat membuat kueri SQL yang lebih efisien dan mudah dipelihara. Cobalah menerapkannya dalam proyek dunia nyata dengan mengikuti langkah-langkah berikut:
- Mulailah dengan kueri sederhana dan latih menyusunnya menggunakan klausa WITH.
- Tantang diri Anda dengan CTE rekursif untuk data hierarkis dan skenario kompleks.
- Fokus pada optimasi kinerja untuk lebih meningkatkan keterampilan SQL Anda.
Ini mengakhiri artikel. Gunakan pengetahuan Anda tentang klausa MySQL WITH dalam pekerjaan dan studi harian Anda.


