Setiap aplikasi hidup dari pertanyaan ya/tidak: apakah pelanggan ini masih aktif, apakah tagihan sudah lunas, apakah pesanan terverifikasi. PostgreSQL menyimpan jawaban pertanyaan seperti itu dalam tipe boolean — hanya satu byte per nilai, dengan tiga kemungkinan isi: true, false, atau NULL. Justru karena tampak sederhana, boolean sering disalahpahami: bentuk literal yang diterimanya lebih banyak dari yang dikira orang, NULL-nya bermain dengan aturan logika tiga nilai, dan penulisan WHERE yang salah membuat baris hilang tanpa pesan error. Chapter ini membedah semuanya dengan tabel pelanggan yang statusnya beragam.
Membuat Tabel dengan Kolom boolean #
Tabel pelanggan berikut memakai dua kolom boolean: aktif (boleh NULL, untuk pelanggan yang statusnya belum dipastikan) dan premium (wajib diisi, default false). Lima barisnya sengaja diisi dengan bentuk literal yang berbeda-beda:
CREATE TABLE pelanggan (
id integer PRIMARY KEY,
nama text NOT NULL,
aktif boolean DEFAULT true,
premium boolean NOT NULL DEFAULT false
);
INSERT INTO pelanggan (id, nama, aktif, premium) VALUES
(1, 'Budi', true, 'f'),
(2, 'Siti', 't', '1'),
(3, 'Toko Maju Jaya', '1', false),
(4, 'Rina', 'no', true),
(5, 'Agus', NULL, 'off');
SELECT id, nama, aktif, premium
FROM pelanggan
ORDER BY id;Output yang Dihasilkan:
CREATE TABLE
INSERT 0 5
id | nama | aktif | premium
----+----------------+-------+---------
1 | Budi | t | f
2 | Siti | t | t
3 | Toko Maju Jaya | t | f
4 | Rina | f | t
5 | Agus | | f
(5 rows)Lima baris masuk dengan lima kombinasi penulisan berbeda, dan hasilnya seragam: kolom aktif berisi t untuk Budi, Siti, dan Toko Maju Jaya; f untuk Rina; serta kosong untuk Agus yang NULL. PostgreSQL menampilkan boolean sebagai t dan f — singkatan satu huruf, bukan kata penuh — dan NULL tampil sebagai kolom kosong. Baris Agus juga memperlihatkan fungsi DEFAULT true: kolom aktif sengaja tidak diberi NOT NULL sehingga NULL diperbolehkan, dan itu keputusan desain yang akan kita bahas pada bagian logika tiga nilai.
Bentuk Literal yang Diterima #
Kata kunci true dan false adalah bentuk utama, tetapi PostgreSQL menerima enam bentuk string untuk masing-masing nilai — berguna saat data datang dari form, file CSV, atau sistem lain:
| Nilai | Bentuk yang diterima |
|---|---|
true | true, 't', 'yes', 'y', 'on', '1' |
false | false, 'f', 'no', 'n', 'off', '0' |
Semua bentuk string tidak peka huruf besar-kecil ('TRUE', 'tRuE' sama sahnya), spasi di awal dan akhir diabaikan, dan awalan unik seperti 'tru' atau 'fal' pun diterima. Kita periksa sebagian bentuk itu langsung di server:
SELECT true AS kata_kunci,
'true'::boolean AS string_true,
'TRUE'::boolean AS huruf_besar,
't'::boolean AS singkat_t;
SELECT false AS kata_kunci,
'f'::boolean AS singkat_f,
'1'::boolean AS angka_satu,
'0'::boolean AS angka_nol;
SELECT 'yes'::boolean AS ya,
'no'::boolean AS tidak,
'on'::boolean AS nyala,
'off'::boolean AS mati;Output yang Dihasilkan:
kata_kunci | string_true | huruf_besar | singkat_t
------------+-------------+-------------+-----------
t | t | t | t
(1 row)
kata_kunci | singkat_f | angka_satu | angka_nol
------------+-----------+------------+-----------
f | f | t | f
(1 row)
ya | tidak | nyala | mati
----+-------+-------+------
t | f | t | f
(1 row)Dua belas ekspresi, dua hasil: semuanya berkurang menjadi t atau f. Perhatikan bahwa bentuk angka '1' dan '0' berupa string berkutip — menulis 1 tanpa kutip bukan literal boolean melainkan integer, dan PostgreSQL tidak mengonversinya secara diam-diam.
Menyaring Baris dengan Kolom boolean #
Kekuatan khas boolean di PostgreSQL: kolomnya bisa dipakai langsung sebagai syarat WHERE tanpa perbandingan apa pun. Tiga query berikut menyaring pelanggan dengan cara yang berbeda:
SELECT id, nama
FROM pelanggan
WHERE aktif
ORDER BY id;
SELECT id, nama
FROM pelanggan
WHERE aktif = true
ORDER BY id;
SELECT id, nama
FROM pelanggan
WHERE NOT premium
ORDER BY id;Output yang Dihasilkan:
id | nama
----+----------------
1 | Budi
2 | Siti
3 | Toko Maju Jaya
(3 rows)
id | nama
----+----------------
1 | Budi
2 | Siti
3 | Toko Maju Jaya
(3 rows)
id | nama
----+----------------
1 | Budi
3 | Toko Maju Jaya
5 | Agus
(3 rows)Mari kita bedah hasil ketiganya:
WHERE aktif: bentuk paling idiomatik — kolom boolean langsung menjadi syarat. Baris Budi, Siti, dan Toko Maju Jaya lolos; Rina (false) dan Agus (NULL) tersaring keluar.WHERE aktif = true: hasilnya identik dengan bentuk pertama. Perbandingan ini sah tetapi berlebihan — komunitas PostgreSQL umumnya menganggapnya noise.WHERE NOT premium: membalik syarat untuk mencari pelanggan non-premium. Budi, Toko Maju Jaya, dan Agus muncul — perhatikan bahwa Agus yangaktif-nya NULL tetap lolos, karena NULL-nya ada di kolom lain yang tidak diperiksa.
Perhatikan pola penting dari query pertama dan ketiga: baris Agus muncul di WHERE NOT premium tetapi tidak di WHERE aktif. Syarat WHERE aktif menuntut nilai true; baris dengan NULL tidak memenuhi tuntutan itu — dan WHERE NOT aktif pun tidak akan menampungnya, seperti berikutnya kita buktikan.
NULL dan Logika Tiga Nilai #
NULL pada kolom boolean tidak berarti “salah” — NULL berarti “tidak diketahui”, dan PostgreSQL memperlakukannya dengan logika tiga nilai SQL. Predikat IS TRUE, IS FALSE, dan IS UNKNOWN adalah satu-satunya cara menguji ketiga keadaan itu secara eksplisit:
SELECT id, nama, aktif
FROM pelanggan
WHERE aktif IS NOT TRUE
ORDER BY id;
SELECT id, nama
FROM pelanggan
WHERE aktif IS UNKNOWN
ORDER BY id;
SELECT (NULL::boolean AND true) IS NULL AS nol_dan_benar,
(NULL::boolean OR false) IS NULL AS nol_atau_salah,
(NOT NULL::boolean) IS NULL AS bukan_nol;Output yang Dihasilkan:
id | nama | aktif
----+------+-------
4 | Rina | f
5 | Agus |
(2 rows)
id | nama
----+------
5 | Agus
(1 row)
nol_dan_benar | nol_atau_salah | bukan_nol
---------------+----------------+-----------
t | t | t
(1 row)Hasilnya memperlihatkan aturan mainnya:
IS NOT TRUEmengambil Rina (nilainyafalse) sekaligus Agus (nilainya NULL) — kebalikan dariWHERE aktifyang hanya mengambil nilaitrue. Bandingkan denganWHERE NOT aktif: bentuk itu hanya menghasilkan Rina, karenaNOT NULLtetap NULL dan NULL tidak lolosWHERE.IS UNKNOWNsecara khusus menangkap baris yang nilainya NULL — hanya Agus.- Query ketiga membuktikan tabel kebenaran tiga nilai:
NULL AND truemenghasilkan NULL (bukan false, karena lawan operand belum tahu nilai sejatinya),NULL OR falsejuga NULL, danNOT NULLtetap NULL. Ketiga hasilnya diuji denganIS NULLdan semuanyat.
Literal yang Tidak Dikenal #
Kelenturan bentuk literal punya batas tegas: string di luar daftar yang diakui ditolak mentah. Kata Bahasa Indonesia yang paling natural justru jadi contoh kegagalannya:
INSERT INTO pelanggan (id, nama, aktif, premium)
VALUES (6, 'Dewi', 'benar', false);Output yang Dihasilkan:
psql:literal-invalid.sql:2: ERROR: invalid input syntax for type boolean: "benar"
LINE 2: VALUES (6, 'Dewi', 'benar', false);
^Error invalid input syntax for type boolean: "benar" muncul begitu string 'benar' dibaca — PostgreSQL tidak menebak makna kata, ia hanya menerima daftar bentuk resmi yang kita lihat di tabel sebelumnya. Serupa dengan ini: SELECT 'ya'::boolean; gagal dengan error yang sama meskipun 'yes' dan 'y' sah. Kalau aplikasi Anda menerima input bebas (misalnya dropdown berbahasa Indonesia), terjemahkan dulu di sisi aplikasi menjadi true/false sebelum mengirimnya ke database.
Dengan ya/tidak beres, sisa katalog tipe data yang belum kita jelajahi adalah yang paling menuntut perhatian detail: tanggal dan waktu — tipe yang formatnya, zona waktunya, dan jebakan kalendernya (termasuk 30 Februari) akan kita bedah di chapter berikutnya.
Referensi #
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
boolean-null.sql
Unduh berkasSELECT id, nama, aktif
FROM pelanggan
WHERE aktif IS NOT TRUE
ORDER BY id;
SELECT id, nama
FROM pelanggan
WHERE aktif IS UNKNOWN
ORDER BY id;
SELECT (NULL::boolean AND true) IS NULL AS nol_dan_benar,
(NULL::boolean OR false) IS NULL AS nol_atau_salah,
(NOT NULL::boolean) IS NULL AS bukan_nol;
buat-tabel.sql
Unduh berkasCREATE TABLE pelanggan (
id integer PRIMARY KEY,
nama text NOT NULL,
aktif boolean DEFAULT true,
premium boolean NOT NULL DEFAULT false
);
INSERT INTO pelanggan (id, nama, aktif, premium) VALUES
(1, 'Budi', true, 'f'),
(2, 'Siti', 't', '1'),
(3, 'Toko Maju Jaya', '1', false),
(4, 'Rina', 'no', true),
(5, 'Agus', NULL, 'off');
SELECT id, nama, aktif, premium
FROM pelanggan
ORDER BY id;
literal-boolean.sql
Unduh berkasSELECT true AS kata_kunci,
'true'::boolean AS string_true,
'TRUE'::boolean AS huruf_besar,
't'::boolean AS singkat_t;
SELECT false AS kata_kunci,
'f'::boolean AS singkat_f,
'1'::boolean AS angka_satu,
'0'::boolean AS angka_nol;
SELECT 'yes'::boolean AS ya,
'no'::boolean AS tidak,
'on'::boolean AS nyala,
'off'::boolean AS mati;
literal-invalid.sql
Unduh berkasINSERT INTO pelanggan (id, nama, aktif, premium)
VALUES (6, 'Dewi', 'benar', false);
where-boolean.sql
Unduh berkasSELECT id, nama
FROM pelanggan
WHERE aktif
ORDER BY id;
SELECT id, nama
FROM pelanggan
WHERE aktif = true
ORDER BY id;
SELECT id, nama
FROM pelanggan
WHERE NOT premium
ORDER BY id;