group_concat di postgreSQL

Pernah pakai fungsi agregat ‘group_concat’ di MySQL? Beberapa waktu lalu aku membutuhkan fungsi agregat tersebut, tapi di PostgreSQL tidak ada fungsi agregat tersebut. FYI, group concat itu kegunaannya untuk melakukan konkatenasi dari nilai-nilai (dalam programming, biasa kita kenal sebagai ‘string joining’ atau yang sejenisnya) yang teragregasi. Misalnya seperti ini:

mysql> SELECT * FROM tags;

+-----+-------+
| key | value |
+-----+-------+
|   1 |     1 |
|   1 |     2 |
|   2 |     1 |
|   2 |     3 |
|   2 |     5 |
|   1 |     7 |
|   3 |     5 |
+-----+-------+

mysql> SELECT key, 
    ->  GROUP_CONCAT(CAST(value as CHAR) 
    ->  ORDER BY value SEPARATOR ', ') as v 
    ->  FROM tags GROUP BY key;

+-----+---------+
| key |    v    |
+-----+---------+
|   1 | 1, 2, 7 |
|   2 | 1, 3, 5 |
|   3 | 5       |
+-----+---------+

Nah, gimana kalau di PostgreSQL? Sebelumnya, aku membuat fungsi agregat sendiri yang menggabungkan ke dalam sebuah string. Tapi ternyata ada cara lain dengan menggunakan fungsi builtin array_to_string yang men’join’ sebuah array. Cara ini generik untuk semua tipe data. Jadi kalau di PostgreSQL, query seperti tadi bisa dituliskan sebagai berikut:

postgres=# SELECT t.key,
postgres-# array_to_string(ARRAY(
postgres-#  SELECT value FROM tags WHERE key = t.key
postgres-#  ORDER BY value), ', ')
postgres-# FROM tags AS t;

Tapi dengan subquery seperti itu, kecepatan menjadi lebih lambat daripada dengan memakai fungsi agregasi. Cara untuk menghindarinya adalah dengan membuat sendiri fungsi agregasi tambahan seperti ini:

CREATE AGGREGATE array_accum (
  sfunc = array_append,
  basetype = anyelement,
  stype = anyarray,
  initcond = '{}'
);

dan querynya menjadi:

array_to_string(array_accum(value), ',')

Tapi hasilnya, nilai ‘value’ di string agregat tidak terurut. Bisa diurutkan dengan mengganti FROM tags AS t dengan (SELECT * FROM tags ORDER BY value) AS t. Haha, ruwet..

Sumber: dari sini dan sini

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s