🧚 Dengar! Beekeeper Studio adalah GUI database yang cepat, modern, dan open source Unduh
7 Januari 2026 Oleh Lucas Gray

Subquery adalah query yang bersarang di dalam query lain. CTE (common table expression) adalah query dalam yang sama, tetapi dipindahkan ke bagian atas statement dengan WITH dan diberi nama, sehingga query yang panjang terbaca sebagai rangkaian langkah. Contoh-contohnya berfungsi di PostgreSQL, MySQL, SQLite, dan SQL Server.

Cara menggunakan CTE dan subquery

Subquery ditulis di tempat ia digunakan: di FROM ia berperan sebagai tabel, dan di WHERE atau SELECT ia menyediakan sebuah nilai atau daftar. CTE didefinisikan lebih dulu, lalu digunakan seperti tabel oleh query berikutnya:

-- Subquery: written where it's used
SELECT columns FROM (SELECT ...) AS name;

-- CTE: named first, then used like a table
WITH name AS (SELECT ...)
SELECT columns FROM name;
SELECT n * 2 AS doubled FROM (SELECT 21 AS n) AS numbers;
-- Output: 42

WITH numbers AS (SELECT 21 AS n)
SELECT n * 2 AS doubled FROM numbers;
-- Output: 42

Pada tabel sungguhan, kedua bentuk ini mengembalikan baris yang sama. Berikut satu filter yang ditulis dengan kedua cara:

-- Input: people
-- first_name | last_name | job      | favorite_food
-- -----------+-----------+----------+--------------
-- Matthew    | Ortiz     | Chef     | cheese
-- Matt       | Novak     | Pilot    | pizza
-- Mattie     | Brooks    | Engineer | cheese
-- Priya      | Nair      | Teacher  | cheese

-- Subquery
SELECT *
FROM (SELECT first_name, last_name, job FROM people WHERE favorite_food = 'cheese') AS cheese_lovers
WHERE first_name LIKE 'Matt%';

-- CTE
WITH cheese_lovers AS (
  SELECT first_name, last_name, job FROM people WHERE favorite_food = 'cheese'
)
SELECT * FROM cheese_lovers
WHERE first_name LIKE 'Matt%';

-- Output of both:
-- first_name | last_name | job
-- -----------+-----------+---------
-- Matthew    | Ortiz     | Chef
-- Mattie     | Brooks    | Engineer

Aturan yang perlu diketahui

  • CTE hanya berlaku untuk satu statement. Query tepat setelah WITH bisa menggunakannya; statement berikutnya tidak bisa. Untuk menyimpan hasil bagi beberapa query, gunakan tabel sementara atau view.
  • Beri nama pada subquery di FROM, seperti AS numbers di atas. MySQL dan SQL Server menolaknya jika tanpa nama.
  • Subquery yang digunakan sebagai satu nilai harus mengembalikan satu baris:
SELECT (SELECT 1 UNION ALL SELECT 2) AS n;
-- ERROR: more than one row returned by a subquery used as an expression
-- (SQLite doesn't complain: it quietly uses the first row, 1)
  • Kecepatannya biasanya sama. Database umumnya merencanakan CTE yang dipakai sekali dengan cara yang sama seperti subquery padanannya, jadi pilih saja yang lebih mudah dibaca.

Sintaks alternatif

CTE yang merujuk dirinya sendiri (lihat di bawah) ditulis dengan WITH RECURSIVE:

-- In SQL Server, leave out RECURSIVE
WITH RECURSIVE counter AS (
  SELECT 1 AS n
  UNION ALL
  SELECT n + 1 FROM counter WHERE n < 3
)
SELECT n FROM counter;

-- Output:
-- n
-- -
-- 1
-- 2
-- 3

Di SQL Server, statement sebelum WITH harus diakhiri titik koma, itulah sebabnya kode T-SQL sering memulai CTE dengan ;WITH.

Kapan sebaiknya menggunakan CTE alih-alih subquery?

Subquery cukup untuk satu langkah kecil. Beralihlah ke CTE saat query memiliki beberapa langkah, membutuhkan hasil yang sama dua kali, atau harus merujuk dirinya sendiri.

Filter terhadap satu nilai hasil perhitungan

Jika query dalam hanya menghasilkan nilai atau daftar untuk dibandingkan, misalnya rata-rata total pesanan, subquery di WHERE adalah cara terpendek untuk menulisnya. CTE juga bisa, tetapi menambahkan nama yang tidak diperlukan.

Pecah query panjang menjadi langkah-langkah bernama

Jika query memiliki beberapa tahap (total per pelanggan, lalu beberapa teratas, lalu daftar akhir), beri nama pada setiap tahap. Tulis beberapa CTE setelah satu WITH, dipisahkan koma: masing-masing bisa menggunakan CTE sebelumnya, dan query terbaca dari atas ke bawah, bukan dari dalam ke luar.

Gunakan hasil yang sama lebih dari sekali

Sebuah statement bisa merujuk CTE sebanyak yang diperlukan, sehingga hasil yang Anda butuhkan dua kali (daftar total beserta rata-ratanya, atau setiap total dan total keseluruhan) cukup ditulis sekali. Dengan subquery, Anda harus menyalin seluruh query dalam.

Menelusuri hierarki

Hanya CTE yang bisa merujuk dirinya sendiri. CTE rekursif dimulai dari beberapa baris dan terus melakukan join kembali ke tabel sampai tidak ada baris baru, begitulah cara menelusuri bagan organisasi atau pohon kategori, maupun menghasilkan deret angka atau tanggal.

Contoh nyata CTE dan subquery

Produk dengan harga di atas rata-rata kategorinya

Subquery merujuk p.category dari query luar, sehingga dihitung untuk kategori masing-masing produk (correlated subquery):

-- Input: products
-- name          | category  | price
-- --------------+-----------+-------
-- Desk Lamp     | Lighting  | 24.99
-- Floor Lamp    | Lighting  | 89.00
-- Office Chair  | Furniture | 149.00
-- Standing Desk | Furniture | 399.00
-- Bookshelf     | Furniture | 120.00

SELECT name, category, price
FROM products p
WHERE price > (
  SELECT AVG(price) FROM products WHERE category = p.category
)
ORDER BY category, name;

-- Output:
-- name          | category  | price
-- --------------+-----------+-------
-- Standing Desk | Furniture | 399.00
-- Floor Lamp    | Lighting  | 89.00

Produk terlaris di setiap kategori

Tiga langkah, masing-masing bernama: jumlahkan unit per produk, beri peringkat produk di setiap kategori, lalu ambil yang teratas:

-- Input: sales
-- id | product      | category  | units
-- ---+--------------+-----------+------
-- 1  | Desk Lamp    | Lighting  | 3
-- 2  | Floor Lamp   | Lighting  | 5
-- 3  | Desk Lamp    | Lighting  | 4
-- 4  | Office Chair | Furniture | 2
-- 5  | Bookshelf    | Furniture | 6

WITH product_totals AS (
  SELECT category, product, SUM(units) AS units
  FROM sales
  GROUP BY category, product
),
ranked AS (
  SELECT category, product, units,
         RANK() OVER (PARTITION BY category ORDER BY units DESC) AS place
  FROM product_totals
)
SELECT category, product, units
FROM ranked
WHERE place = 1
ORDER BY category;

-- Output:
-- category  | product   | units
-- ----------+-----------+------
-- Furniture | Bookshelf | 6
-- Lighting  | Desk Lamp | 7

Pangsa penjualan setiap wilayah

region_totals digunakan dua kali: sekali untuk baris-barisnya, dan sekali di dalam subquery untuk total keseluruhan:

-- Input: orders
-- id | region | amount
-- ---+--------+--------
-- 1  | North  | 1200.00
-- 2  | South  | 450.00
-- 3  | North  | 300.00
-- 4  | West   | 800.00
-- 5  | South  | 250.00

WITH region_totals AS (
  SELECT region, SUM(amount) AS total
  FROM orders
  GROUP BY region
)
SELECT
  region,
  total,
  ROUND(100.0 * total / (SELECT SUM(total) FROM region_totals), 1) AS pct_of_sales
FROM region_totals
ORDER BY total DESC;

-- Output:
-- region | total   | pct_of_sales
-- -------+---------+-------------
-- North  | 1500.00 | 50.0
-- West   | 800.00  | 26.7
-- South  | 700.00  | 23.3

Jika ditulis dengan subquery, query GROUP BY akan muncul dua kali.

Rantai atasan seorang karyawan

Mulai dari satu karyawan dan ikuti manager_id ke atas sampai habis:

-- Input: employees
-- id | name      | manager_id
-- ---+-----------+-----------
-- 1  | Maya Chen | NULL
-- 2  | Sam Ortiz | 1
-- 3  | Jo Kim    | 2
-- 4  | Lee Ross  | 2
-- 5  | Ana Diaz  | 1

-- In SQL Server, leave out RECURSIVE
WITH RECURSIVE chain AS (
  SELECT id, name, manager_id, 0 AS level
  FROM employees
  WHERE name = 'Jo Kim'
  UNION ALL
  SELECT e.id, e.name, e.manager_id, chain.level + 1
  FROM employees e
  JOIN chain ON e.id = chain.manager_id
)
SELECT level, name FROM chain ORDER BY level;

-- Output:
-- level | name
-- ------+----------
-- 0     | Jo Kim
-- 1     | Sam Ortiz
-- 2     | Maya Chen

Bacaan lanjutan tentang CTE dan subquery

Di blog ini:

Dokumentasi resmi:

Beekeeper Studio Adalah GUI Database Gratis & Open Source

Tool query & editor SQL terbaik yang pernah saya pakai. Semua yang saya butuhkan untuk mengelola database ada di sini. - ⭐⭐⭐⭐⭐ Mit

Beekeeper Studio cepat, intuitif, dan mudah digunakan. Beekeeper mendukung banyak sekali database, dan berjalan mulus di Windows, Mac, dan Linux.

Versi Linux Beekeeper punya fitur 100% lengkap, tanpa potong kompas, tanpa kompromi fitur.

Apa Kata Pengguna Tentang Beekeeper Studio

★★★★★
"Beekeeper Studio sepenuhnya menggantikan alur kerja SQL lama saya. Cepat, intuitif, dan membuat pekerjaan database kembali menyenangkan."
— Alex K., Database Developer
★★★★★
"Saya sudah mencoba banyak GUI database, tetapi Beekeeper punya keseimbangan sempurna antara fitur dan kesederhanaan. Langsung jalan."
— Sarah M., Full Stack Engineer

Siap Meningkatkan Alur Kerja SQL Anda?

download Unduh Gratis