STRING_AGG dan GROUP_CONCAT di SQL
TL;DR
STRING_AGG (PostgreSQL dan SQL Server) dan GROUP_CONCAT (MySQL dan SQLite) adalah fungsi agregasi yang nggabungin nilai teks dari banyak baris jadi satu string, dipisah dengan pemisah yang kamu tentuin. Keduanya dipakai bareng GROUP BY, dan bisa diurutkan pakai ORDER BY di dalamnya serta disaring duplikatnya pakai DISTINCT. Contoh paling umum: bikin daftar produk per order jadi satu kolom.
STRING_AGG di PostgreSQL dan GROUP_CONCAT di MySQL nggabungin nilai teks dari banyak baris jadi satu string yang dipisah pemisah pilihanmu, dalam satu GROUP BY.
Bayangin tabel detail order yang tiap produknya satu baris. Kalau kamu mau nampilin semua produk per order dalam satu kolom, dipisah koma, dua fungsi ini yang ngerjain. Nggak perlu loop atau proses di luar database.
Di artikel ini kamu bakal belajar sintaks keduanya, cara ngatur urutan dan buang duplikat, plus contoh nyata dari data order UMKM.
Apa itu STRING_AGG dan GROUP_CONCAT?
Keduanya fungsi agregasi teks. Kalau fungsi kayak SUM ngeringkas angka jadi satu total, STRING_AGG dan GROUP_CONCAT ngeringkas teks dari banyak baris jadi satu string gabungan. STRING_AGG dipakai di PostgreSQL dan SQL Server, sedangkan GROUP_CONCAT dipakai di MySQL dan SQLite.
Karena keduanya fungsi agregasi, mereka selalu jalan bareng GROUP BY. Sama kayak agregasi lain, dia ngeringkas satu grup jadi satu baris hasil. Bedanya cuma outputnya berupa teks, bukan angka.
Gimana sintaks STRING_AGG di PostgreSQL?
STRING_AGG minta dua argumen: kolom teks yang mau digabung dan pemisahnya. Kamu bisa nambahin ORDER BY di dalam kurung buat ngatur urutan hasilnya.
SELECT
order_id,
STRING_AGG(produk, ', ' ORDER BY produk) AS daftar_produk
FROM detail_order
GROUP BY order_id;
Hasilnya satu baris per order, dan kolom daftar_produk isinya semua produk order itu dipisah koma, terurut alfabet. ORDER BY di dalam STRING_AGG penting biar urutannya konsisten tiap kali query dijalanin.
Kalau ada nilai kembar dan kamu cuma mau yang unik, tambahin DISTINCT:
SELECT
pelanggan_id,
STRING_AGG(DISTINCT kategori, ', ') AS kategori_dibeli
FROM detail_order
GROUP BY pelanggan_id;
Gimana sintaks GROUP_CONCAT di MySQL?
GROUP_CONCAT beda dikit. Pemisahnya ditulis pakai kata kunci SEPARATOR, dan kalau nggak diisi, default-nya koma tanpa spasi. ORDER BY dan DISTINCT juga ditaruh di dalam kurung.
SELECT
order_id,
GROUP_CONCAT(produk ORDER BY produk SEPARATOR ', ') AS daftar_produk
FROM detail_order
GROUP BY order_id;
Satu hal yang wajib kamu tau: GROUP_CONCAT punya batas panjang hasil. Default-nya cuma 1024 karakter, dan kalau hasilnya lebih panjang, teksnya kepotong diam-diam tanpa error. Naikin batasnya lewat setting session.
SET SESSION group_concat_max_len = 100000;
STRING_AGG vs GROUP_CONCAT: bandingannya
| Aspek | STRING_AGG | GROUP_CONCAT |
|---|---|---|
| Database | PostgreSQL, SQL Server | MySQL, SQLite |
| Pemisah | Argumen kedua | Kata kunci SEPARATOR |
| Pemisah default | Wajib diisi | Koma tanpa spasi |
| Batas panjang | Nggak ada batas ketat | 1024 karakter (bisa dinaikin) |
Konsepnya sama, tinggal sesuaikan dengan database yang kamu pakai. Kalau kamu sering butuh agregasi lain di query yang sama, baca conditional aggregation dengan CASE buat kombinasiin ringkasan angka dan teks.
Contoh kasus: daftar produk per order toko_berkah
Aku pakai data toko_berkah, tabel detail_order dengan 6.500 baris dari 1.800 order selama satu bulan. Tiap baris satu produk. Aku mau ringkas jadi satu baris per order plus daftar produknya.
SELECT
order_id,
COUNT(*) AS jumlah_item,
STRING_AGG(produk, ', ' ORDER BY produk) AS daftar_produk
FROM detail_order
GROUP BY order_id;
Dari hasilnya aku sekalian hitung rata-rata item per order. Ketemu angka 3,6 produk per order. Yang menarik, 22% order (sekitar 396 order) isinya cuma satu produk, biasanya rokok atau pulsa. Order satu item ini nyumbang volume transaksi besar tapi nilai kecil.
Dengan daftar produk yang udah digabung, aku gampang scan order mana yang sering muncul bareng, misalnya kopi sachet selalu barengan gula. Info ini berguna buat nyusun paket bundling.
Kesalahan umum pakai STRING_AGG dan GROUP_CONCAT
- Lupa GROUP BY. Tanpa GROUP BY, semua baris kegabung jadi satu string raksasa.
- Hasil GROUP_CONCAT kepotong. Batas 1024 karakter di MySQL bikin daftar panjang terpangkas tanpa peringatan.
- Urutan nggak konsisten. Tanpa ORDER BY di dalam fungsi, urutan hasilnya bisa beda tiap kali query jalan.
- Nyampur NULL. Nilai NULL dilewati, tapi kadang bikin pemisah dobel kalau kamu nggabungin kolom hasil concat manual.
FAQ
Pertanyaan yang sering muncul soal STRING_AGG dan GROUP_CONCAT.
Apa beda STRING_AGG dan GROUP_CONCAT?
Fungsinya sama, cuma beda database dan sintaks. STRING_AGG dipakai di PostgreSQL dan SQL Server, dan pemisahnya ditaruh sebagai argumen kedua. GROUP_CONCAT dipakai di MySQL dan SQLite, dan pemisahnya ditulis pakai kata kunci SEPARATOR. GROUP_CONCAT juga punya batas panjang default 1024 karakter yang bisa bikin hasil kepotong, sedangkan STRING_AGG nggak punya batas ketat itu. Pilih sesuai database yang kamu pakai.
Kenapa hasil GROUP_CONCAT-ku kepotong di tengah?
MySQL punya setting bernama group_concat_max_len yang default-nya 1024 karakter. Kalau hasil gabunganmu lebih panjang dari itu, MySQL motong teksnya tanpa ngasih error sama sekali. Ini jebakan yang sering bikin data hilang diam-diam. Solusinya naikin batasnya lewat perintah SET SESSION group_concat_max_len sama angka yang lebih besar, misalnya 100000, sebelum kamu jalanin query-nya.
Gimana cara ngurutin hasil di dalam STRING_AGG?
Kamu taruh ORDER BY di dalam kurung fungsi, tepat setelah pemisah. Contohnya STRING_AGG(produk, ', ' ORDER BY produk) bakal ngurutin produk secara alfabet sebelum digabung. Ini penting karena tanpa ORDER BY, urutan hasilnya nggak dijamin dan bisa beda tiap query dijalanin. Di MySQL GROUP_CONCAT, ORDER BY ditaruh sebelum kata kunci SEPARATOR di dalam kurung yang sama.
Bisakah STRING_AGG buang nilai duplikat?
Bisa. Tambahin kata kunci DISTINCT tepat sebelum nama kolom, jadi STRING_AGG(DISTINCT kategori, ', '). Ini bakal ngilangin nilai kembar sebelum digabung, jadi tiap nilai cuma muncul sekali di hasil. GROUP_CONCAT di MySQL juga dukung DISTINCT dengan cara yang sama. Fitur ini berguna banget kalau kamu mau daftar kategori unik yang pernah dibeli seorang pelanggan tanpa pengulangan.
Penutup
STRING_AGG dan GROUP_CONCAT bikin kamu ngeringkas banyak baris teks jadi satu kolom, langsung di database. Ingat tiga hal: keduanya butuh GROUP BY, pakai ORDER BY di dalam fungsi biar urutannya stabil, dan di MySQL naikin group_concat_max_len kalau daftarnya panjang.
Sekali kamu terbiasa, laporan yang butuh daftar per grup jadi gampang. Mau bandingin dengan cara Python? Baca pandas groupby agg. Detail lengkap ada di dokumentasi PostgreSQL aggregate functions. Mau latihan query agregasi? Kulik di NgulikSQL.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Artikel terkait
7 Antipattern SQL yang Bikin Query Lambat
Tujuh pola SQL yang diam-diam bikin query lambat, dari SELECT bintang, fungsi di kolom filter, sampai OFFSET besar. Plus cara benerin tiap satunya.
CTE vs Subquery vs Temp Table: Mana Lebih Cepat
CTE, subquery, dan temp table sama-sama bikin hasil sementara, tapi performanya beda. Ini panduan milih yang mana buat query kamu.
Partisi Tabel di SQL untuk Data Besar
Partisi tabel memecah satu tabel besar jadi potongan kecil biar query cuma baca bagian yang relevan. Ini cara bikin dan kapan kamu butuh.