Secara umum, saya setuju dengan saran @kgrittn. Lakukan.
Tetapi untuk menjawab pertanyaan dasar Anda tentang concat()
:Fungsi baru concat()
berguna jika Anda perlu menangani nilai nol - dan null tidak dikesampingkan dalam pertanyaan Anda maupun pertanyaan yang Anda rujuk.
Jika anda dapat mengesampingkan nilai nol, operator gabungan lama (standar SQL) yang baik ||
masih merupakan pilihan terbaik, dan jawaban @luis baik-baik saja:
SELECT col_a || col_b;
Jika salah satu kolom Anda bisa nol, hasilnya akan nol dalam kasus itu. Anda bisa bertahan dengan COALESCE
:
SELECT COALESCE(col_a, '') || COALESCE(col_b, '');
Tapi itu cepat membosankan dengan lebih banyak argumen. Di situlah concat()
masuk, yang tidak pernah mengembalikan null, bahkan jika semua argumen adalah nol. Per dokumentasi:
Argumen NULL diabaikan.
SELECT concat(col_a, col_b);
Kasing pojok yang tersisa untuk kedua alternatif adalah di mana semua kolom masukan adalah nol dalam hal ini kita masih mendapatkan string kosong ''
, tetapi orang mungkin ingin null sebagai gantinya (setidaknya saya mau). Salah satu cara yang mungkin:
SELECT CASE
WHEN col_a IS NULL THEN col_b
WHEN col_b IS NULL THEN col_a
ELSE col_a || col_b
END;
Ini menjadi lebih kompleks dengan lebih banyak kolom dengan cepat. Sekali lagi, gunakan concat()
tetapi tambahkan tanda centang untuk kondisi khusus:
SELECT CASE WHEN (col_a, col_b) IS NULL THEN NULL
ELSE concat(col_a, col_b) END;
Bagaimana cara kerjanya? (col_a, col_b)
adalah notasi singkatan untuk ekspresi tipe baris ROW (col_a, col_b)
. Dan tipe baris hanya null jika semua kolom adalah nol. Penjelasan detail:
- BUKAN NULL batasan pada sekumpulan kolom
Juga, gunakan concat_ws()
untuk menambahkan pemisah antar elemen (ws
untuk "dengan pemisah").
Ekspresi seperti yang ada di jawaban Kevin:
SELECT $1.zipcode || ' - ' || $1.city || ', ' || $1.state;
membosankan untuk mempersiapkan nilai nol di PostgreSQL 8.3 (tanpa concat()
). Satu cara (dari banyak):
SELECT COALESCE(
CASE
WHEN $1.zipcode IS NULL THEN $1.city
WHEN $1.city IS NULL THEN $1.zipcode
ELSE $1.zipcode || ' - ' || $1.city
END, '')
|| COALESCE(', ' || $1.state, '');
Volatilitas fungsi hanya STABLE
concat()
dan concat_ws()
adalah STABLE
fungsi, bukan IMMUTABLE
karena mereka dapat menjalankan fungsi keluaran tipe data (seperti timestamptz_out
) yang bergantung pada setelan lokal.
Penjelasan oleh Tom Lane.
Ini melarang penggunaan langsungnya dalam ekspresi indeks. Jika Anda tahu bahwa hasilnya sebenarnya tidak dapat diubah dalam kasus Anda, Anda dapat mengatasinya dengan IMMUTABLE
pembungkus fungsi. Contoh di sini:
- Apakah PostgreSQL mendukung kumpulan "aksen tidak sensitif"?