Sebuah subkueri adalah kueri SQL (Bahasa Kueri Terstruktur) yang bersarang di dalam kueri SQL lain. Perintah tempat subquery bersarang disebut sebagai kueri induk. Subqueries digunakan untuk pra-proses data yang digunakan dalam query induk. Subquery dapat diterapkan di SELECT
, INSERT
, UPDATE
, dan DELETE
operasi.
Ketika subquery dieksekusi, subquery diproses terlebih dahulu sebelum query induk. Saat membangun aplikasi MySQL, menggunakan subquery menawarkan beberapa keuntungan:
- Mereka memecah pernyataan SQL menjadi unit logis sederhana, yang dapat membuatnya lebih mudah untuk dipahami dan dipelihara. Dengan kata lain, subkueri membantu mengisolasi bagian kueri yang kompleks.
- Mereka menghilangkan kebutuhan untuk menggunakan
UNION
yang kompleks pernyataan danJOIN
pernyataan. - Mereka digunakan untuk menegakkan integritas referensial dalam skenario di mana kunci asing tidak diterapkan.
- Mereka membantu pengembang mengkodekan logika bisnis ke dalam kueri MySQL.
Dalam panduan ini Anda akan belajar:
- Cara menggunakan subkueri yang berkorelasi
- Cara menggunakan subkueri berkorelasi dalam operator perbandingan
- Cara menggunakan subkueri sebagai tabel turunan
Sebelum Anda Mulai
Untuk mengikuti panduan ini, pastikan Anda memiliki yang berikut:
-
Jika Anda belum melakukannya, buat akun Linode dan Compute Instance. Lihat panduan Memulai Linode dan Membuat Instans Komputasi.
-
Ikuti panduan Menyiapkan dan Mengamankan Instans Komputasi untuk memperbarui sistem Anda. Anda mungkin juga ingin mengatur zona waktu, mengkonfigurasi nama host Anda, membuat akun pengguna terbatas, dan memperkuat akses SSH.
-
Perangkat lunak server MySQL (atau MariaDB) diinstal pada Linode Anda. Silakan merujuk ke bagian MySQL, yang berisi panduan yang menjelaskan cara menginstal MySQL pada beberapa distribusi Linux.
Menyiapkan Basis Data
Untuk memahami cara kerja subkueri, buat database sampel terlebih dahulu. Database sampel ini digunakan untuk menjalankan kueri contoh yang berbeda dalam panduan ini:
-
SSH
ke server Anda dan masuk ke MySQL sebagai root:mysql -u root -p
Saat diminta, masukkan kata sandi root server MySQL Anda dan tekan Enter untuk melanjutkan. Perhatikan bahwa kata sandi root server MySQL Anda tidak sama dengan kata sandi root untuk Linode Anda.
Catatan
Jika kata sandi Anda tidak diterima, Anda mungkin perlu menjalankan perintah sebelumnya dengan
sudo
:sudo mysql -u root -p
-
Jika kata sandi Anda diterima, Anda akan melihat perintah MySQL:
mysql >
Catatan
Jika Anda menggunakan MariaDB, Anda mungkin melihat prompt seperti berikut ini:
MariaDB [(none)]>
-
Untuk membuat database sampel bernama
test_db
, jalankan:CREATE DATABASE test_db;
Anda akan melihat output ini, yang mengonfirmasi bahwa database berhasil dibuat:
Query OK, 1 row affected (0.01 sec)
-
Beralih ke
test_db
basis data:USE test_db;
Anda akan melihat keluaran ini:
Database changed
-
Anda telah membuat
test_db
dan memilihnya. Selanjutnya, buat tabel dengan namacustomers
:CREATE TABLE customers ( customer_id BIGINT PRIMARY KEY AUTO_INCREMENT, customer_name VARCHAR(50) ) ENGINE = InnoDB;
Anda akan melihat keluaran ini:
Query OK, 0 rows affected (0.03 sec)
-
Tambahkan beberapa catatan ke
customers
meja. JalankanINSERT
di bawah ini perintah satu per satu:INSERT INTO customers(customer_name) VALUES ('JOHN PAUL'); INSERT INTO customers(customer_name) VALUES ('PETER DOE'); INSERT INTO customers(customer_name) VALUES ('MARY DOE'); INSERT INTO customers(customer_name) VALUES ('CHRISTINE JAMES'); INSERT INTO customers(customer_name) VALUES ('MARK WELL'); INSERT INTO customers(customer_name) VALUES ('FRANK BRIAN');
Output ini ditampilkan setelah setiap record dimasukkan:
Query OK, 1 row affected (0.00 sec) ...
-
Verifikasi bahwa informasi pelanggan telah dimasukkan ke dalam database. Jalankan
SELECT
ini perintah:SELECT * FROM customers;
Anda akan melihat daftar pelanggan ini:
+-------------+-----------------+ | customer_id | customer_name | +-------------+-----------------+ | 1 | JOHN PAUL | | 2 | PETER DOE | | 3 | MARY DOE | | 4 | CHRISTINE JAMES | | 5 | MARK WELL | | 6 | FRANK BRIAN | +-------------+-----------------+ 6 rows in set (0.00 sec)
-
Buat
sales
meja. Tabel ini menggunakan kolomcustomer_id
untuk mereferensikancustomers
tabel:CREATE TABLE sales ( order_id BIGINT PRIMARY KEY AUTO_INCREMENT, customer_id BIGINT, sales_amount DECIMAL(17,2) ) ENGINE = InnoDB;
Keluaran ini muncul:
Query OK, 0 rows affected (0.03 sec)
-
Selanjutnya, isi
sales
tabel dengan beberapa catatan. JalankanINSERT
di bawah ini perintah satu per satu:INSERT INTO sales (customer_id, sales_amount) VALUES ('1','25.75'); INSERT INTO sales (customer_id, sales_amount) VALUES ('2','85.25'); INSERT INTO sales (customer_id, sales_amount) VALUES ('5','3.25'); INSERT INTO sales (customer_id, sales_amount) VALUES ('4','200.75'); INSERT INTO sales (customer_id, sales_amount) VALUES ('5','88.10'); INSERT INTO sales (customer_id, sales_amount) VALUES ('1','100.00'); INSERT INTO sales (customer_id, sales_amount) VALUES ('2','45.00'); INSERT INTO sales (customer_id, sales_amount) VALUES ('4','15.80');
Output ini ditampilkan setelah setiap record dimasukkan:
Query OK, 1 row affected (0.01 sec) ...
-
Verifikasi data di
sales
meja. JalankanSELECT
ini perintah:SELECT * FROM sales;
Daftar data penjualan ini sekarang harus ditampilkan:
+----------+-------------+--------------+ | order_id | customer_id | sales_amount | +----------+-------------+--------------+ | 1 | 1 | 25.75 | | 2 | 2 | 85.25 | | 3 | 5 | 3.25 | | 4 | 4 | 200.75 | | 5 | 5 | 88.10 | | 6 | 1 | 100.00 | | 7 | 2 | 45.00 | | 8 | 4 | 15.80 | +----------+-------------+--------------+ 8 rows in set (0.00 sec)
Setelah menyiapkan database dan tabel terkait, sekarang Anda dapat mengimplementasikan subquery yang berbeda di MySQL.
Cara Menggunakan Subquery Berkorelasi
Subkueri berkorelasi adalah tipe kueri bersarang yang menggunakan nilai dari kueri induk. Jenis kueri ini merujuk kueri induk dengan kolom. Kueri bersarang dieksekusi sekali untuk setiap baris dalam kueri induk.
Contoh di bawah ini menyajikan kueri yang memilih semua pelanggan. Di dalam kueri, ada subkueri berkorelasi yang mengambil jumlah total penjualan untuk setiap pelanggan dari sales
tabel.
-
Jalankan kueri contoh:
SELECT customer_id, customer_name, (SELECT SUM(sales_amount) FROM sales WHERE customer_id = customers.customer_id) as total_sales_amount FROM customers;
Dalam contoh ini, subkuerinya adalah
SELECT SUM(sales_amount) FROM sales WHERE customer_id = customers.customer_id
, yang muncul dalam tanda kurung.Daftar total penjualan yang dilakukan pelanggan muncul:
+-------------+-----------------+--------------------+ | customer_id | customer_name | total_sales_amount | +-------------+-----------------+--------------------+ | 1 | JOHN PAUL | 125.75 | | 2 | PETER DOE | 130.25 | | 3 | MARY DOE | NULL | | 4 | CHRISTINE JAMES | 216.55 | | 5 | MARK WELL | 91.35 | | 6 | FRANK BRIAN | NULL | +-------------+-----------------+--------------------+ 6 rows in set (0.00 sec)
Output di atas dari subquery yang berkorelasi dapat memberi Anda daftar ringkasan pesanan pelanggan. Harap diperhatikan, karena
customer_id
s3
dan6
tidak memiliki catatan terkait di tabel penjualan,total_sales_amount
their adalahNULL
. -
Cara yang lebih elegan untuk menampilkan daftar ini adalah dengan mengembalikan
0
bukannyaNULL
untuk pelanggan dengan penjualan nol. Untuk melakukannya, lampirkan output yang dihasilkan oleh subquery denganIFNULL(expression, 0)
penyataan. Jalankan perintah yang diperbarui ini:SELECT customer_id, customer_name, IFNULL((SELECT SUM(sales_amount) FROM sales WHERE customer_id = customers.customer_id), 0) as total_sales_amount FROM customers;
Keluaran berikut muncul. MySQL mengembalikan 0,00 untuk semua baris yang seharusnya mengembalikan
NULL
nilai.+-------------+-----------------+--------------------+ | customer_id | customer_name | total_sales_amount | +-------------+-----------------+--------------------+ | 1 | JOHN PAUL | 125.75 | | 2 | PETER DOE | 130.25 | | 3 | MARY DOE | 0.00 | | 4 | CHRISTINE JAMES | 216.55 | | 5 | MARK WELL | 91.35 | | 6 | FRANK BRIAN | 0.00 | +-------------+-----------------+--------------------+ 6 rows in set (0.00 sec)
Pendekatan ini membantu memastikan bahwa keluaran tidak merusak perhitungan lebih lanjut pada catatan.
Cara Menggunakan Subquery Berkorelasi dalam Operator Perbandingan
Subqueries berguna untuk memindahkan logika bisnis ke tingkat query database. Kasus penggunaan bisnis berikut menampilkan subkueri berkorelasi yang ditempatkan di dalam klausa WHERE dari kueri induk:
-
Pertimbangkan skenario di mana Anda ingin mendapatkan daftar semua pelanggan yang terdaftar di database yang tidak memiliki penjualan terkait. Anda dapat menggunakan subquery bersama dengan operator perbandingan MySQL
NOT IN
dan ambil kembali pelanggan ini:SELECT customer_id, customer_name FROM customers WHERE customer_id NOT IN (SELECT customer_id FROM sales);
Dalam contoh ini, subkuerinya adalah
SELECT customer_id FROM sales
, yang muncul dalam tanda kurung. Perintah SQL di atas menampilkan daftar dua pelanggan yang tidak ditemukan di tabel penjualan:+-------------+---------------+ | customer_id | customer_name | +-------------+---------------+ | 3 | MARY DOE | | 6 | FRANK BRIAN | +-------------+---------------+ 2 rows in set (0.00 sec)
Dalam lingkungan produksi, Anda dapat menggunakan kumpulan rekaman semacam ini untuk membuat keputusan bisnis yang lebih baik. Misalnya, Anda dapat membuat skrip menggunakan bahasa lain seperti PHP atau Python untuk mengirim email kepada pelanggan ini dan menanyakan apakah mereka memiliki masalah dalam melakukan pemesanan.
-
Kasus penggunaan lainnya adalah dalam pembersihan data. Misalnya, Anda dapat menggunakan subkueri untuk menghapus pelanggan yang belum pernah memesan:
DELETE FROM customers WHERE customer_id NOT IN (SELECT customer_id FROM sales);
Perintah SQL di atas menghapus dua pelanggan dan menampilkan yang berikut:
Query OK, 2 rows affected (0.01 sec)
Jika Anda menjalankan perintah untuk membuat daftar semua pelanggan lagi, pelanggan ini seharusnya tidak lagi muncul di tabel:
SELECT * FROM customers;
Output di bawah ini mengkonfirmasi bahwa pelanggan tanpa pesanan terkait telah dihapus:
+-------------+-----------------+ | customer_id | customer_name | +-------------+-----------------+ | 1 | JOHN PAUL | | 2 | PETER DOE | | 4 | CHRISTINE JAMES | | 5 | MARK WELL | +-------------+-----------------+ 4 rows in set (0.00 sec)
Cara Menggunakan Subquery sebagai Tabel Turunan
Ketika subquery digunakan dalam FROM
klausa kueri induk, mereka disebut sebagai tabel turunan . Mereka sangat penting ketika menerapkan kueri kompleks yang jika tidak memerlukan VIEW
MySQL , JOIN
, atau UNION
ayat. Tabel turunan ada dalam kueri yang membuatnya dan tidak disimpan secara permanen ke dalam database.
Ketika subquery digunakan sebagai tabel turunan, mereka mengisolasi bagian-bagian berbeda dari pernyataan SQL. Dengan kata lain, subquery menyediakan ekspresi tabel yang disederhanakan yang dapat digunakan dalam lingkup kueri induk.
Catatan Ingat, setiap tabel turunan harus diberi alias.
Jalankan perintah di bawah ini untuk membuat subquery tabel turunan yang beralias sebagai order_summary
:
SELECT customer_id
FROM
(
SELECT
customer_id,
count(order_id) as total_orders
FROM sales
group by customer_id
) as order_summary
WHERE order_summary.total_orders > 1;
CatatanDalam perintah ini, subquery muncul dalam tanda kurung sebagai:
SELECT customer_id, count(order_id) as total_orders FROM sales group by customer_id
Perintah di atas menanyakan tabel penjualan untuk menentukan pelanggan dengan lebih dari 1 pesanan. Saat Anda menjalankan kueri, output ini muncul:
+-------------+
| customer_id |
+-------------+
| 1 |
| 2 |
| 5 |
| 4 |
+-------------+
4 rows in set (0.00 sec)
Daftar di atas menunjukkan empat customer_id
s yang memiliki lebih dari satu ordo. Sebagai contoh kasus penggunaan bisnis, Anda dapat menggunakan kueri semacam itu dalam skrip yang memberikan bonus kepada pelanggan untuk pembelian berikutnya.
Informasi Lebih Lanjut
Anda mungkin ingin berkonsultasi dengan sumber daya berikut untuk informasi tambahan tentang topik ini. Meskipun ini disediakan dengan harapan dapat bermanfaat, harap perhatikan bahwa kami tidak dapat menjamin keakuratan atau ketepatan waktu materi yang dihosting secara eksternal.
- Subkueri MySQL