Operator perbandingan = menuntut kita mengetahui isi kolom secara persis, karakter demi karakter. Dunia nyata sering hanya memberi petunjuk sebagian: “nama produknya mengandung kata Kertas”, “kotanya berawalan huruf S”, “nomor pesanannya berakhiran 01”. Operator LIKE menangani pencocokan pola semacam itu dengan bantuan dua karakter wildcard. Pada chapter ini kita akan berlatih keduanya, melihat mengapa LIKE tanpa wildcard menjadi pencocokan persis, membuktikan bahwa LIKE bawaan tidak membedakan huruf besar-kecil, menangani karakter khusus dengan ESCAPE, lalu menutup dengan catatan performa yang membedakan pola berawalan tetap dari pola berawalan wildcard.

Menyiapkan Tabel Latihan #

Kita pakai tabel produk dan pelanggan dengan data yang sama seperti chapter-chapter sebelumnya:

sql
DROP DATABASE IF EXISTS belajar_filter;
CREATE DATABASE belajar_filter;
USE belajar_filter;

Output yang Dihasilkan:

text
Query OK, 0 rows affected, 1 warning (0.00 sec)

Query OK, 1 row affected (0.00 sec)

Database changed
sql
CREATE TABLE produk (
  id INT AUTO_INCREMENT PRIMARY KEY,
  nama VARCHAR(100) NOT NULL,
  kategori VARCHAR(50) NOT NULL,
  harga DECIMAL(10,2) NOT NULL,
  stok INT NOT NULL DEFAULT 0
);

INSERT INTO produk (nama, kategori, harga, stok) VALUES
  ('Buku Tulis Sidu 38', 'Alat Tulis', 4500.00, 120),
  ('Pensil 2B', 'Alat Tulis', 3000.00, 200),
  ('Penghapus Putih', 'Alat Tulis', 2500.00, 150),
  ('Pulpen Gel Hitam', 'Alat Tulis', 5000.00, 80),
  ('Spidol Permanen', 'Alat Tulis', 10000.00, 45),
  ('Kertas HVS A4', 'Kertas', 27500.00, 20),
  ('Kertas Origami', 'Kertas', 12000.00, 60),
  ('Amplop Coklat', 'Kertas', 800.00, 300),
  ('Stipo 12 Gram', 'Perekat', 6000.00, 0),
  ('Selotip Bening', 'Perekat', 8000.00, 55);

Output yang Dihasilkan:

text
Query OK, 0 rows affected (0.00 sec)

Query OK, 10 rows affected (0.00 sec)
Records: 10  Duplicates: 0  Warnings: 0
sql
CREATE TABLE pelanggan (
  id INT AUTO_INCREMENT PRIMARY KEY,
  nama VARCHAR(100) NOT NULL,
  kota VARCHAR(50) NOT NULL,
  telepon VARCHAR(20) NULL
);

INSERT INTO pelanggan (nama, kota, telepon) VALUES
  ('Budi Santoso', 'Bandung', '0812-5000-1001'),
  ('Siti Rahayu', 'Jakarta', '0813-5000-1002'),
  ('Andi Wijaya', 'Surabaya', NULL),
  ('Dewi Lestari', 'Bandung', '0815-5000-1004'),
  ('Rian Hidayat', 'Yogyakarta', NULL),
  ('Maya Putri', 'Medan', '0817-5000-1006'),
  ('Eko Prasetyo', 'Semarang', NULL),
  ('Fitri Handayani', 'Bandung', '0819-5000-1008');

Output yang Dihasilkan:

text
Query OK, 0 rows affected (0.00 sec)

Query OK, 8 rows affected (0.00 sec)
Records: 8  Duplicates: 0  Warnings: 0

Dua Karakter Wildcard #

Kekuatan LIKE berasal dari dua karakter khusus di dalam pola. Tabel berikut merangkum keduanya:

WildcardArtiContoh pola
%nol atau lebih karakter apa pun'S%', '%Kertas%'
_tepat satu karakter apa pun'_ensil%'

Kita mulai dari pola berawalan tetap. Query berikut mencari seluruh produk yang namanya diawali huruf S:

sql
SELECT nama, kategori
FROM produk
WHERE nama LIKE 'S%'
ORDER BY id;

Output yang Dihasilkan:

text
+-----------------+------------+
| nama            | kategori   |
+-----------------+------------+
| Spidol Permanen | Alat Tulis |
| Stipo 12 Gram   | Perekat    |
| Selotip Bening  | Perekat    |
+-----------------+------------+
3 rows in set (0.00 sec)

Tiga produk lolos: Spidol Permanen, Stipo 12 Gram, dan Selotip Bening — semua berawalan S, panjang sisanya bebas. Wildcard % menyerap “karakter apa pun, sebanyak apa pun”, termasuk nol karakter; itulah sebabnya pola 'Pensil 2B%' akan tetap cocok dengan nilai persis 'Pensil 2B'.

Wildcard % juga bisa diletakkan di awal pola untuk mencari nilai yang mengandung potongan kata:

sql
SELECT nama, kategori
FROM produk
WHERE nama LIKE '%Kertas%'
ORDER BY id;

Output yang Dihasilkan:

text
+----------------+----------+
| nama           | kategori |
+----------------+----------+
| Kertas HVS A4  | Kertas   |
| Kertas Origami | Kertas   |
+----------------+----------+
2 rows in set (0.00 sec)

Dua produk berisi potongan Kertas ditemukan — Kertas HVS A4 dan Kertas Origami — meskipun potongan itu muncul di awal nama. Pola %Kertas% membaca “ada kata Kertas di mana saja”. Versi ketiga menempatkan wildcard di akhir pola untuk mencari akhiran:

sql
SELECT nama, kota
FROM pelanggan
WHERE kota LIKE '%a'
ORDER BY id;

Output yang Dihasilkan:

text
+--------------+------------+
| nama         | kota       |
+--------------+------------+
| Siti Rahayu  | Jakarta    |
| Andi Wijaya  | Surabaya   |
| Rian Hidayat | Yogyakarta |
+--------------+------------+
3 rows in set (0.00 sec)

Tiga kota berakhiran huruf a lolos: Jakarta, Surabaya, dan Yogyakarta. Terakhir, pola bisa memuat wildcard di tengah — awalan dan akhiran tetap, tengah bebas:

sql
SELECT nama
FROM produk
WHERE nama LIKE 'P%l'
ORDER BY id;

Output yang Dihasilkan:

text
Empty set (0.00 sec)

Satu-satunya yang cocok adalah Pensil 2B: berawalan P, berakhiran l, dan 2B di tengah diserap wildcard. Pola berbentuk 'ka%a' mengikuti prinsip yang sama — awalan ka, akhiran a, isi tengah apa pun.

Wildcard Garis Bawah untuk Satu Karakter #

Wildcard _ jauh lebih ketat: menggantikan tepat satu karakter, tidak lebih tidak kurang:

sql
SELECT nama
FROM produk
WHERE nama LIKE '_ensil%'
ORDER BY id;

Output yang Dihasilkan:

text
+-----------+
| nama      |
+-----------+
| Pensil 2B |
+-----------+
1 row in set (0.00 sec)

Pola '_ensil%' menemukan Pensil 2B: karakter pertama apa pun (diisi P), disusul huruf ensil, sisanya bebas. Bandingkan dengan '%ensil%' yang juga akan cocok — perbedaannya baru terasa saat kita perlu mengunci posisi: pola 'S_idol%' menuntut tepat satu karakter di antara S dan idol, sedangkan 'S%idol%' menerima nama seperti Sekring Spidol sekalipun.

LIKE Tanpa Wildcard #

Pola tanpa wildcard sama sekali menjadi pencocokan persis:

sql
SELECT nama, harga
FROM produk
WHERE nama LIKE 'Pensil 2B';

Output yang Dihasilkan:

text
+-----------+---------+
| nama      | harga   |
+-----------+---------+
| Pensil 2B | 3000.00 |
+-----------+---------+
1 row in set (0.00 sec)

Satu baris ditemukan — perilaku yang sama dengan nama = 'Pensil 2B'. Dalam praktik, tulis = untuk pencocokan persis karena maksudnya eksplisit, dan sisahkan LIKE khusus untuk pola yang memang memuat wildcard.

LIKE Tidak Membedakan Huruf Besar-Kecil #

Perilaku LIKE mengikuti collation kolom, dan collation bawaan kita case-insensitive (pernah kita buktikan di chapter Operator Perbandingan). Pola berikut ditulis dengan huruf kecil semua:

sql
SELECT nama, kategori
FROM produk
WHERE nama LIKE 'kertas%'
ORDER BY id;

Output yang Dihasilkan:

text
+----------------+----------+
| nama           | kategori |
+----------------+----------+
| Kertas HVS A4  | Kertas   |
| Kertas Origami | Kertas   |
+----------------+----------+
2 rows in set (0.00 sec)

Kedua produk Kertas tetap ditemukan meski pola memakai k kecil — kesepakatan yang nyaman untuk pencarian dari input pengguna, ketimbang mengubah-ubah kapitalisasi di kode aplikasi.

Karakter Escape #

Bagaimana bila data kita justru memuat karakter % atau _ sebagai bagian nilainya, misalnya kode promo promo_50? Tanpa escape, wildcard bekerja sebagaimana biasanya dan hasilnya menyesatkan:

sql
SELECT 'promo_50' LIKE 'promo_50' AS pola_1, 'promoX50' LIKE 'promo_50' AS pola_2;

Output yang Dihasilkan:

text
+--------+--------+
| pola_1 | pola_2 |
+--------+--------+
|      1 |      1 |
+--------+--------+
1 row in set (0.00 sec)

Pola 'promo_50' cocok dengan kedua nilai: pada promoX50, karakter _ menyerap huruf X. Untuk memaksa _ dibaca sebagai karakter biasa, sertakan escape \ di depannya:

sql
SELECT 'promo_50' LIKE 'promo\_50' AS pola_1, 'promoX50' LIKE 'promo\_50' AS pola_2;

Output yang Dihasilkan:

text
+--------+--------+
| pola_1 | pola_2 |
+--------+--------+
|      1 |      0 |
+--------+--------+
1 row in set (0.00 sec)

Sekarang hanya promo_50 yang cocok — \_ berarti “garis bawah literal”. Backslash adalah karakter escape bawaan LIKE. Bila data kita banyak memuat backslash (misalnya path Windows), klausa ESCAPE mengganti karakter escape ke simbol lain:

sql
SELECT 'promo_50' LIKE 'promo|_50' ESCAPE '|' AS pola_1, 'promoX50' LIKE 'promo|_50' ESCAPE '|' AS pola_2;

Output yang Dihasilkan:

text
+--------+--------+
| pola_1 | pola_2 |
+--------+--------+
|      1 |      0 |
+--------+--------+
1 row in set (0.00 sec)

Dengan ESCAPE '|', karakter | berperan sebagai escape sehingga |_ berarti garis bawah literal — hasilnya sama persis dengan versi backslash.

Catatan Performa: Posisi Wildcard Menentukan Biaya #

Dua pola %Kertas% dan Kertas% sama-sama benar secara hasil, tetapi biayanya berbeda jauh di tabel besar. Pola dengan awalan tetap seperti 'Kertas%' memungkinkan MySQL memakai index pada kolom nama — pencarian langsung menuju blok data yang berawalan Kertas, layaknya kita membuka kamus di halaman huruf K. Sebaliknya, pola berawalan wildcard seperti '%Kertas%' harus membaca setiap baris tabel karena potongan kata bisa bersembunyi di posisi mana pun; index tidak bisa membantu. Pada tabel latihan sepuluh baris bedanya tak terasa, tetapi pada tabel berjuta-juta baris pola %kata% adalah pemindai penuh yang lambat.

Membersihkan Database Latihan #

Latihan pola teks selesai. Kita jatuhkan database latihan bersama kedua tabelnya:

sql
DROP DATABASE belajar_filter;

Output yang Dihasilkan:

text
Query OK, 2 rows affected (0.00 sec)

Referensi #

Pencocokan pola menyelesaikan pencarian teks, tetapi menyisakan satu warga kelas istimewa: nilai NULL yang tidak pernah cocok dengan pola, pembanding, maupun operator logika manapun. Chapter Is NULL berikutnya menghadapinya langsung dengan kondisi khusus IS NULL dan IS NOT NULL.