TL;DR
CONCAT SQL menggabungkan dua nilai teks atau lebih jadi satu string dengan sintaks CONCAT(teks1, teks2, ...). Kelebihannya dibanding operator pipe ganda (||): CONCAT memperlakukan NULL sebagai string kosong, jadi satu kolom kosong gak bikin seluruh hasilnya jadi NULL. Kalau kamu butuh pemisah otomatis antar kolom, pakai CONCAT_WS yang cuma perlu nulis pemisahnya sekali.
CONCAT nyambungin dua nilai teks atau lebih jadi satu string. Sintaksnya CONCAT(teks1, teks2, ...), dan tiap argumen bisa berupa kolom atau teks langsung dalam tanda kutip.
Kolom nama_depan dan nama_belakang yang harus jadi satu kolom nama lengkap buat laporan? Ini fungsinya.
Yang bikin CONCAT menarik bukan sintaksnya. Itu gampang. Yang penting adalah gimana dia nanganin NULL, karena di situ operator alternatifnya bisa diam-diam ngerusak seluruh hasil query kamu.
CONCAT adalah fungsi string SQL yang menggabungkan beberapa nilai jadi satu teks. Fungsinya nerima dua argumen atau lebih, dan nilai NULL diperlakukan sebagai string kosong.
SELECT CONCAT(nama_depan, ' ', nama_belakang) AS nama_lengkap
FROM pelanggan;
-- Budi Santoso
-- Siti Rahayu
-- Andi ← nama_belakang NULL, hasilnya tetap keluar
-- Dewi Lestari
Perhatiin baris Andi. Kolom nama_belakang-nya NULL, tapi CONCAT tetap ngasih "Andi ", dengan spasi nyangkut di belakang, tapi setidaknya barisnya gak ilang.
Spasi nempel itu bisa dibersihin pakai TRIM. Yang gak bisa diperbaiki adalah baris yang jadi NULL total. Itu yang terjadi kalau kamu pakai operator pipe ganda.
Operator || adalah cara standar ANSI buat gabungin teks. Jalan di PostgreSQL, Oracle, SQLite.
SELECT nama_depan || ' ' || nama_belakang AS nama_lengkap
FROM pelanggan;
-- Budi Santoso
-- Siti Rahayu
-- NULL ← seluruh baris ilang!
-- Dewi Lestari
Baris Andi jadi NULL. Bukan "Andi", bukan string kosong. NULL.
Ini perilaku NULL yang standar: apa pun yang dioperasikan sama NULL hasilnya NULL. Kalau kamu belum akrab, baca NULL di SQL.
Bahayanya: query-nya gak error. Dia jalan dengan tenang, dan kamu baru sadar ada 340 baris yang kosong pas laporan udah dikirim ke bos.
| CONCAT | Operator || | |
|---|---|---|
| NULL diperlakukan sebagai | String kosong | NULL (nular ke semua) |
| Standar ANSI | Nggak | Ya |
| PostgreSQL | Ada | Ada |
| MySQL | Ada | Nggak (|| = OR) |
| SQL Server | Ada | Nggak (pakai +) |
Kalau kamu tetap mau pakai ||, amanin dulu tiap kolom yang mungkin kosong:
SELECT nama_depan || ' ' || COALESCE(nama_belakang, '') AS nama_lengkap
FROM pelanggan;
COALESCE ngubah NULL jadi string kosong, dan barisnya selamat.
Ini versi yang bakal kamu pakai paling sering buat data nyata.
SELECT CONCAT_WS(', ', jalan, kelurahan, kota, provinsi, kode_pos)
AS alamat_lengkap
FROM pelanggan;
WS singkatan dari with separator. Argumen pertama adalah pemisahnya, sisanya kolom yang mau digabung.
Dua keuntungan sekaligus. Pemisahnya cuma ditulis sekali. Bandingin sama CONCAT biasa, di mana kamu harus nyelipin ', ' empat kali. Dan kolom NULL otomatis dilewatin.
-- CONCAT biasa, baris Siti (kelurahan NULL):
Jl. Diponegoro No. 8, , Surabaya, Jawa Timur, 60241
↑ koma dobel
-- CONCAT_WS, baris yang sama:
Jl. Diponegoro No. 8, Surabaya, Jawa Timur, 60241
Bersih. Gak ada koma nyangkut.
Toko_berkah kirim 120 paket per hari. Alamat pengiriman kesimpan di lima kolom terpisah, dan sekitar 18% baris punya kolom kelurahan yang kosong, karena pelanggan gak isi waktu checkout.
Query buat bikin label:
SELECT
CONCAT(nama_depan, ' ', COALESCE(nama_belakang, '')) AS penerima,
CONCAT_WS(', ', jalan, kelurahan, kota) AS alamat,
CONCAT_WS(' ', provinsi, kode_pos) AS wilayah
FROM pelanggan;
Hasilnya:
penerima | alamat | wilayah
Budi Santoso | Jl. Merdeka No. 12, Cihapit, Bandung | Jawa Barat 40114
Siti Rahayu | Jl. Diponegoro No. 8, Surabaya | Jawa Timur 60241
Andi | Jl. Sudirman No. 45, Petisah, Medan | Sumatera Utara 20112
Kalau query ini ditulis pakai || tanpa COALESCE, baris Andi bakal ilang total dari hasil. Dan 18% baris yang kelurahannya kosong juga bakal ilang. Dari 120 paket, 22 label bakal blank.
CONCAT ngerjain konversi tipe otomatis di kebanyakan database:
SELECT CONCAT('Pelanggan #', id, ' - ', kota) AS label
FROM pelanggan;
-- Pelanggan #1 - Bandung
Tapi jangan andelin itu. Di beberapa database (terutama PostgreSQL versi lama dan Oracle), kamu perlu CAST eksplisit:
SELECT CONCAT('Pelanggan #', CAST(id AS VARCHAR), ' - ', kota) AS label
FROM pelanggan;
Lebih panjang, tapi jalan di mana-mana. Detail konversi tipe ada di artikel CAST dan CONVERT SQL.
Pakai || tanpa mikirin NULL. Ini yang paling sering, dan paling berbahaya karena gak ngasih error. Cek dulu: SELECT COUNT(*) FROM pelanggan WHERE nama_belakang IS NULL; sebelum nulis query gabungan.
Ngira CONCAT nambahin pemisah otomatis. CONCAT(nama_depan, nama_belakang) ngasih "BudiSantoso". Spasi harus ditulis sebagai argumen sendiri, atau pakai CONCAT_WS.
Pakai CONCAT di WHERE. WHERE CONCAT(kota, provinsi) = 'BandungJawa Barat' bikin index gak kepakai dan database scan seluruh tabel. Bandingin kolom aslinya satu-satu.
CONCAT di Oracle cuma nerima 2 argumen. Buat gabung tiga kolom, kamu harus tumpuk: CONCAT(CONCAT(a, b), c). Atau pakai || yang lebih enak dibaca. Perilaku lengkap per database bisa kamu cek di dokumentasi fungsi string PostgreSQL.
Perbedaan terbesarnya di NULL. Operator || bikin seluruh hasilnya NULL kalau ada satu nilai NULL. CONCAT memperlakukan NULL sebagai string kosong, jadi barisnya tetap keluar. Operator || standar ANSI (PostgreSQL, Oracle), CONCAT jalan di hampir semua database termasuk MySQL dan SQL Server.
CONCAT_WS = concatenate with separator. Pemisah ditulis sekali di argumen pertama, kolom NULL otomatis dilewatin tanpa ninggalin koma dobel. Ini pilihan terbaik buat gabung alamat atau data yang sering bolong.
Kalau kamu pakai ||, itu perilaku normal. Satu NULL nular ke seluruh ekspresi. Bungkus tiap kolom yang mungkin kosong pakai COALESCE(kolom, ''). Kalau kamu di Oracle, ingat CONCAT di sana cuma nerima dua argumen.
Bisa, tapi ekspresinya ditulis ulang di GROUP BY, bukan aliasnya. Di PostgreSQL kamu bisa pakai nomor kolom: GROUP BY 1. GROUP BY di hasil fungsi juga bikin index kolom aslinya gak kepakai.
Dua poin penting soal CONCAT.
Pertama: || ngerusak baris kalau ada NULL, CONCAT nggak. Kalau data kamu punya kolom opsional (dan hampir selalu punya), pilih CONCAT atau bungkus pakai COALESCE.
Kedua: buat gabungan lebih dari dua kolom dengan pemisah sama, CONCAT_WS ngerjain semuanya lebih rapi.
Jalanin query di bagian sql_queries artikel ini. Aku sengaja masukin dua baris dengan kolom NULL, biar kamu lihat sendiri bedanya CONCAT dan || pas ketemu data bolong.
Lanjut ke SUBSTRING SQL kalau kamu perlu motong teks, bukan nyambungin.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Analisa per kuartal, hari kerja, atau musim jadi ribet kalau tiap query ngitung ulang atribut tanggal. Tabel kalender nyimpen semua atribut itu sekali, biar tinggal di-JOIN.
Laporan penjualan harian sering bolong di hari tanpa transaksi. Ini cara bikin deret tanggal lengkap di SQL biar tiap hari muncul, walau nilainya nol.
Struktur organisasi tersimpan sebagai kolom id_atasan yang saling nunjuk. Ini cara narik rantai jabatan, hitung total bawahan, dan span of control cuma pakai SQL.