Data mentah di kolom jarang langsung siap tampil: harga perlu pembulatan, nama pelanggan kadang menyimpan spasi berlebih, dan NULL harus diganti nilai cadangan. Fungsi scalar menyelesaikan semua itu di dalam query itu sendiri — satu nilai masuk, satu nilai keluar, diproses baris demi baris. Ini berbeda dari fungsi agregat yang meringkas banyak baris menjadi satu seperti yang sudah kita bahas pada Chapter Fungsi Agregat. Kita akan mengelompokkan puluhan fungsi bawaan ke dalam lima kategori dan mengujinya satu per satu.
Data Contoh #
Chapter ini memakai satu tabel dari domain toko. Kolom stok sengaja memuat NULL untuk latihan penanganan nilai kosong:
CREATE TABLE produk (
id INTEGER PRIMARY KEY,
nama TEXT NOT NULL,
harga REAL NOT NULL,
stok INTEGER
);
INSERT INTO produk (id, nama, harga, stok) VALUES
(1, 'Kopi Gayo', 45000.0, 20),
(2, 'Teh Melati', 18000.0, 35),
(3, 'Gula Aren', 25000.0, NULL),
(4, 'Kopi Toraja', 52000.0, 10),
(5, 'Sirup Vanila', 27500.5, 0);Fungsi Matematika #
abs() mengembalikan nilai mutlak dan round() membulatkan angka pecahan ke jumlah digit tertentu. Perhatikan bahwa round() selalu menghasilkan nilai REAL — lihat 3.0 dan 2.0 pada output:
SELECT abs(-2500), round(31714.2857142857, 2), round(2.5), round(2);Output yang Dihasilkan:
2500|31714.29|3.0|2.0min() dan max() punya dua wajah: dengan satu argumen kolom keduanya bekerja sebagai agregat, tetapi dengan dua argumen atau lebih keduanya menjadi fungsi scalar yang memilih nilai terkecil atau terbesar di antara argumen-argumennya:
SELECT min(3, 1, 2), max(3, 1, 2);Output yang Dihasilkan:
1|3Bentuk scalar ini berguna untuk membatasi nilai di tiap baris, misalnya menjepit harga agar tidak melewati 30000:
SELECT nama, min(harga, 30000) AS dibatasi FROM produk ORDER BY id;Output yang Dihasilkan:
Kopi Gayo|30000
Teh Melati|18000.0
Gula Aren|25000.0
Kopi Toraja|30000
Sirup Vanila|27500.5min() mengembalikan argumen yang menang apa adanya — 30000 tetap integer karena yang menang adalah angka kedua, sementara 18000.0 tetap REAL karena yang menang adalah harga dari kolom.
Fungsi Teks #
length() menghitung jumlah karakter, upper() dan lower() mengubah kapitalisasi:
SELECT length('Kopi Gayo'), upper('kopi'), lower('GAYO');Output yang Dihasilkan:
9|KOPI|gayosubstr() memotong teks. Argumen kedua adalah posisi awal (bisa negatif, dihitung dari belakang) dan argumen ketiga adalah jumlah karakter:
SELECT substr('Kopi Gayo', 1, 4), substr('Kopi Gayo', 6), substr('Kopi Gayo', -5);Output yang Dihasilkan:
Kopi|Gayo| Gayoinstr() mencari posisi pertama sebuah substring (mengembalikan 0 bila tidak ditemukan), sedangkan replace() mengganti semua kemunculannya:
SELECT instr('Kopi Gayo', 'Gayo'), replace('Kopi Gayo', 'Gayo', 'Toraja');Output yang Dihasilkan:
6|Kopi TorajaKeluarga trim() membersihkan spasi: trim() dari kedua sisi, ltrim() dari kiri, rtrim() dari kanan. Tanda kurung siku membuat hasil pemotongan terlihat jelas:
SELECT '[' || trim(' Kopi Gayo ') || ']', '[' || ltrim(' Kopi ') || ']', '[' || rtrim(' Kopi ') || ']';Output yang Dihasilkan:
[Kopi Gayo]|[Kopi ]|[ Kopi]Memformat Keluaran dengan printf dan format #
printf() menyusun teks dari placeholder seperti %s untuk teks dan %d untuk bilangan bulat — persis rekan SQL dari fungsi printf() di bahasa C. Mulai SQLite 3.38 tersedia alias bernama format() dengan perilaku identik. Flag koma mengelompokkan ribuan:
SELECT printf('%s: %d unit', 'Kopi Gayo', 20), format('Rp%,d', 45000);Output yang Dihasilkan:
Kopi Gayo: 20 unit|Rp45,000Fungsi Logika dan Penanganan NULL #
Empat fungsi berikut paling sering menyelamatkan query dari nilai kosong. coalesce() mengembalikan argumen non-NULL pertama, ifnull() versi dua-argumennya, nullif() mengembalikan NULL bila kedua argumen sama, dan iif() (hadir sejak SQLite 3.32) mengevaluasi percabangan:
SELECT coalesce(NULL, NULL, 'Cadangan'), ifnull(NULL, 0), nullif('a', 'a'), nullif('a', 'b');Output yang Dihasilkan:
Cadangan|0||aiif(kondisi, a, b) mengembalikan a bila kondisi benar dan b bila salah — padanan CASE WHEN yang ringkas:
SELECT nama, iif(stok IS NULL, 'tidak diketahui', 'tercatat') AS status
FROM produk ORDER BY id;Output yang Dihasilkan:
Kopi Gayo|tercatat
Teh Melati|tercatat
Gula Aren|tidak diketahui
Kopi Toraja|tercatat
Sirup Vanila|tercatatFungsi Pemeriksa Nilai #
Kelompok terakhir memeriksa tipe dan representasi nilai. typeof() mengembalikan nama tipe, quote() menghasilkan bentuk literal SQL, hex() mengonversi teks ke heksadesimal per byte UTF-8, dan unicode() mengembalikan kode karakter pertama:
SELECT typeof(harga), quote(nama), hex('Ab'), unicode('B') FROM produk WHERE id = 1;Output yang Dihasilkan:
real|'Kopi Gayo'|4162|66Tabel Ringkas per Kategori #
| Kategori | Fungsi | Kegunaan |
|---|---|---|
| Matematika | abs(), round(), min()/max() multi-arg | Nilai mutlak, pembulatan, pembatasan nilai per baris |
| Teks | length(), upper(), lower(), substr(), instr(), replace(), trim(), ltrim(), rtrim() | Membersihkan dan memotong teks |
| Format | printf(), format() | Menyusun teks keluaran dengan placeholder |
| Logika | coalesce(), ifnull(), nullif(), iif() | Nilai cadangan dan percabangan |
| Inspeksi | typeof(), quote(), hex(), unicode() | Memeriksa tipe dan representasi nilai |
Sebagai penutup, kita gabungkan beberapa kategori menjadi satu daftar harga yang rapi:
SELECT format('%-12s', trim(nama)) AS nama,
format('Rp%,d', round(harga)) AS harga,
iif(stok IS NULL, 'stok tak diketahui', stok || ' unit') AS info_stok
FROM produk
ORDER BY harga DESC;Output yang Dihasilkan:
Kopi Toraja |Rp52,000|10 unit
Kopi Gayo |Rp45,000|20 unit
Sirup Vanila|Rp27,501|0 unit
Gula Aren |Rp25,000|stok tak diketahui
Teh Melati |Rp18,000|35 unitMari kita bedah query di atas baris per baris:
- Baris 1 (
format('%-12s', trim(nama))): Fungsitrim()membuang spasi di kedua sisi nama, laluformat()meratakannya di ruang 12 karakter agar kolom lurus; tanda minus membuat teks rata kiri. - Baris 2 (
format('Rp%,d', round(harga))):round()membulatkan harga ke bilangan bulat REAL, kemudian placeholder%dmengonversinya ke integer dan flag koma menambahkan pemisah ribuan — perhatikan27500.5menjadiRp27,501. - Baris 3 (
iif(stok IS NULL, ...)): Cabang pertama mengisi teks untuk stok kosong; cabang kedua merekatkan angka stok dengan kataunitlewat operator||. - Baris 5 (
ORDER BY harga DESC): Urutan menurun membuat produk termahal berada di atas, sehingga output deterministik dan mudah dibaca.
Fungsi scalar memproses nilai pada baris yang sama. Tantangan berikutnya adalah nilai yang berubah seiring waktu — tanggal dan waktu — yang dibahas pada Chapter Bekerja dengan Tanggal dan Waktu.