CTE Adalah Subquery yang Diberi Nama
Common Table Expression (CTE) adalah subquery yang kamu keluarkan dan beri nama. Alih-alih menyarangkan SELECT di dalam SELECT lain, kamu mendefinisikannya di bagian atas dengan WITH, memberinya nama, lalu memakai nama itu di query utama seolah-olah sebuah tabel.
Bentuknya selalu sama:
Baca dari atas ke bawah: pertama, bangun hasil bernama customer_totals, lalu jalankan query terhadap hasil itu. CTE berperilaku seperti view sementara yang hanya ada selama satu pernyataan ini berjalan.
Query yang Sama Tanpa CTE
Berikut logika yang sama ditulis sebagai subquery, supaya kamu bisa melihat apa yang digantikan oleh CTE:
Jawabannya sama. Tapi perhatikan urutan membacanya: matamu harus masuk ke dalam tanda kurung, mencari tahu apa yang sedang dihitung, lalu keluar lagi. Versi CTE terbaca sesuai urutan pekerjaannya: definisikan hasil antara, lalu pakai. Pada query kecil, bedanya tidak terasa. Pada query dengan tiga atau empat langkah, inilah perbedaan antara kode yang bisa dibaca sekilas dan kode yang harus dipecahkan seperti teka-teki.
Beberapa CTE dalam Satu Query
Kamu bisa merangkai beberapa CTE, dipisahkan dengan koma. Setiap CTE bisa merujuk CTE yang didefinisikan sebelumnya, jadi kamu membangun rangkaian langkah yang masing-masing bernama:
Satu WITH, lalu definisi CTE yang dipisahkan koma. CTE kedua (big_spenders) membaca dari CTE pertama (customer_totals) sama seperti membaca dari tabel. SELECT utama ditulis setelah definisi CTE terakhir.
Kesalahan yang sering terjadi: menulis WITH lagi di depan CTE kedua. Jangan, karena itu syntax error. Satu WITH mencakup semuanya.
Merujuk CTE Lebih dari Sekali
Di sinilah CTE benar-benar unggul dibanding subquery. Kalau kamu butuh hasil antara yang sama di dua tempat, CTE memungkinkanmu menghitungnya sekali dan merujuknya dua kali:
CTE itu dirujuk dua kali: sekali untuk menghitung rata-rata, sekali sebagai sumber utama. Tanpa CTE, kamu harus menduplikasi query GROUP BY, dan setiap perubahan pada query itu harus dilakukan di dua tempat.
CTE dengan INSERT, UPDATE, dan DELETE
CTE tidak hanya untuk SELECT. Kamu bisa menaruh klausa WITH di depan INSERT, UPDATE, atau DELETE untuk memakai subquery bernama dalam operasi tulis:
CTE itu menjelaskan baris mana yang perlu ditandai. INSERT ... SELECT memakainya sebagai sumber. Trik yang sama bekerja dengan DELETE FROM ... WHERE id IN (SELECT id FROM cte) untuk penghapusan bertahap yang logika pemilihan barisnya rumit.
Kapan Memakai CTE
Beberapa patokan praktis:
- Query punya lebih dari satu langkah logis. Mengagregasi, lalu memfilter berdasarkan hasil agregat, lalu melakukan join pada hasilnya: itu adalah rangkaian langkah, dan satu CTE per langkah membuatnya mudah dibaca.
- Kalau tidak, kamu akan mengulang subquery yang sama. Definisikan sekali, rujuk dua kali.
- Subquery itu layak diberi nama. Kalau kamu akan menaruh komentar di atas subquery untuk menjelaskan apa yang diwakilinya, nama CTE adalah komentar itu, dan sintaksnya memastikan nama itu selalu ada.
- Kamu akan menulis query rekursif. Itu hanya bisa dilakukan dengan
WITH RECURSIVE, yang dibahas di halaman berikutnya.
Kapan tidak perlu repot:
- Satu subquery sederhana yang dipakai di satu tempat.
WHERE id IN (SELECT id FROM ...)sudah cukup apa adanya. - Query yang performanya sangat penting dan kamu sudah memastikan bahwa menulis logikanya langsung di dalam query lebih membantu. SQLite biasanya tidak memperlakukan CTE sebagai pembatas optimasi seketat beberapa database lain, tapi untuk jalur yang sering dijalankan, ada baiknya diperiksa dengan
EXPLAIN QUERY PLAN.
Contoh Lengkap
Kalau semuanya digabungkan, berikut laporan kecil yang mencari pesanan terbesar setiap customer dan perbandingannya dengan rata-rata pesanan mereka:
Dua CTE, masing-masing mengerjakan satu hal. SELECT utama memformat hasilnya. Kamu bisa membaca query ini dari atas ke bawah dan memahami setiap langkahnya secara terpisah, dan itulah inti dari CTE.
Berikutnya: CTE Rekursif
Semua yang sejauh ini kita bahas adalah CTE biasa: subquery bernama yang dievaluasi sekali. SQLite juga mendukung WITH RECURSIVE, yaitu CTE yang merujuk dirinya sendiri untuk menelusuri hierarki, membuat deret angka, atau menjelajahi graph. Itu halaman berikutnya.
Pertanyaan yang sering diajukan
Apa itu CTE di SQLite?
Common Table Expression adalah subquery bernama yang ditaruh di bagian atas SELECT, INSERT, UPDATE, atau DELETE. Kamu membukanya dengan kata kunci WITH, memberinya nama, lalu merujuk nama itu di query utama seolah-olah sebuah tabel. CTE membuat query yang rumit mudah dibaca karena kamu bisa membangun hasilnya selangkah demi selangkah.
Apa bedanya CTE dan subquery di SQLite?
Keduanya bisa menghasilkan hasil yang sama persis: CTE pada dasarnya adalah subquery yang dikeluarkan dan diberi nama. Bedanya ada di keterbacaan dan pemakaian ulang: CTE bisa dirujuk beberapa kali dalam query yang sama, dan namanya menjelaskan apa yang diwakili oleh hasil antara itu. Untuk filter sekali pakai, subquery sudah cukup; untuk logika bertahap, CTE lebih unggul.
Bisakah saya memakai beberapa CTE dalam satu query SQLite?
Bisa. Setelah WITH pertama, pisahkan CTE tambahan dengan koma, dan jangan mengulang WITH. Setiap CTE bisa merujuk CTE yang didefinisikan sebelumnya, jadi kamu bisa membangun rangkaian langkah yang masing-masing bernama. SELECT utama ditulis setelah CTE terakhir.