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.
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.
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;
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;
| 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.
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.
Pertanyaan yang sering muncul soal 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.
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.
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.
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.
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.
Kolom waktu isinya angka gede kayak 1704067200 dan bikin bingung? Itu Unix timestamp. Ini cara ngubahnya jadi tanggal beneran di SQL, plus balik lagi.
Data transaksi tersimpan UTC, tapi laporan harus jam WIB. Kalau salah konversi, angka penjualan tengah malam bisa kecatat di tanggal yang salah. Ini cara handle timezone di SQL dengan benar.
Nambah 30 hari ke tanggal invoice, ngurangin sebulan buat cari periode lalu, ngitung selisih hari antar order. Semua itu aritmetika tanggal, dan SQL punya operator INTERVAL buat ngerjainnya.