PostgreSQL 9.0 atau lebih baru:
Versi terbaru Postgres (sejak akhir 2010) memiliki string_agg(expression, delimiter)
fungsi yang akan melakukan persis apa yang ditanyakan, bahkan memungkinkan Anda menentukan string pembatas:
SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;
Postgres 9.0 juga menambahkan kemampuan untuk menentukan ORDER BY
klausa dalam ekspresi agregat apa pun ; jika tidak, pesanan tidak ditentukan. Jadi sekarang Anda dapat menulis:
SELECT company_id, string_agg(employee, ', ' ORDER BY employee)
FROM mytable
GROUP BY company_id;
Atau memang:
SELECT string_agg(actor_name, ', ' ORDER BY first_appearance)
PostgreSQL 8.4 atau lebih baru:
PostgreSQL 8.4 (pada 2009) memperkenalkan fungsi agregatarray_agg(expression)
yang menggabungkan nilai-nilai ke dalam array. Kemudian array_to_string()
dapat digunakan untuk memberikan hasil yang diinginkan:
SELECT company_id, array_to_string(array_agg(employee), ', ')
FROM mytable
GROUP BY company_id;
string_agg
untuk versi pra-8.4:
Jika ada orang yang menemukan ini mencari shim yang kompatibel untuk pra-9.0 database, adalah mungkin untuk mengimplementasikan semuanya string_agg
kecuali ORDER BY
klausa.
Jadi dengan definisi di bawah ini harus berfungsi sama seperti pada 9.x Postgres DB:
SELECT string_agg(name, '; ') AS semi_colon_separated_names FROM things;
Tetapi ini akan menjadi kesalahan sintaksis:
SELECT string_agg(name, '; ' ORDER BY name) AS semi_colon_separated_names FROM things;
--> ERROR: syntax error at or near "ORDER"
Diuji pada PostgreSQL 8.3.
CREATE FUNCTION string_agg_transfn(text, text, text)
RETURNS text AS
$$
BEGIN
IF $1 IS NULL THEN
RETURN $2;
ELSE
RETURN $1 || $3 || $2;
END IF;
END;
$$
LANGUAGE plpgsql IMMUTABLE
COST 1;
CREATE AGGREGATE string_agg(text, text) (
SFUNC=string_agg_transfn,
STYPE=text
);
Variasi khusus (semua versi Postgres)
Sebelum 9.0, tidak ada fungsi agregat bawaan untuk merangkai string. Implementasi kustom yang paling sederhana ( disarankan oleh Vajda Gabo dalam posting milis ini , di antara banyak lainnya) adalah dengan menggunakan textcat
fungsi bawaan (yang ada di belakang ||
operator):
CREATE AGGREGATE textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);
Ini CREATE AGGREGATE
dokumentasinya.
Ini hanya menempelkan semua string bersama, tanpa pemisah. Untuk mendapatkan "," yang disisipkan di antara mereka tanpa di bagian akhir, Anda mungkin ingin membuat fungsi penggabungan Anda sendiri dan menggantinya dengan "textcat" di atas. Inilah yang saya kumpulkan dan uji pada 8.3.12:
CREATE FUNCTION commacat(acc text, instr text) RETURNS text AS $$
BEGIN
IF acc IS NULL OR acc = '' THEN
RETURN instr;
ELSE
RETURN acc || ', ' || instr;
END IF;
END;
$$ LANGUAGE plpgsql;
Versi ini akan menampilkan koma bahkan jika nilai di baris adalah nol atau kosong, sehingga Anda mendapatkan output seperti ini:
a, b, c, , e, , g
Jika Anda lebih suka menghapus koma ekstra untuk menghasilkan ini:
a, b, c, e, g
Kemudian tambahkan tanda ELSIF
centang ke fungsi seperti ini:
CREATE FUNCTION commacat_ignore_nulls(acc text, instr text) RETURNS text AS $$
BEGIN
IF acc IS NULL OR acc = '' THEN
RETURN instr;
ELSIF instr IS NULL OR instr = '' THEN
RETURN acc;
ELSE
RETURN acc || ', ' || instr;
END IF;
END;
$$ LANGUAGE plpgsql;