Bagaimana cara menggabungkan kolom dalam Postgres SELECT?

145

Saya memiliki dua kolom string adan bdalam sebuah tabel foo.

select a, b from foomengembalikan nilai adan b. Namun, rangkaian adan btidak bekerja. Saya mencoba :

select a || b from foo

dan

select  a||', '||b from foo

Pembaruan dari komentar: kedua kolom adalah tipe character(2).

Alex
sumber
... atau texttipe lain ?
PM 77-1
@acfrancis Karena OP bilang concatenatesaya ragu dia berurusan dengan tipe numerik, meskipun PostgreSQL juga akan menangani beberapa dari mereka. Lihat di sini: postgresql.org/docs/9.1/static/functions-string.html
PM 77-1
Ya, kolom ini adalah karakter (2). "+" tidak berfungsi - "Tidak ada operator yang cocok dengan nama dan tipe argumen yang diberikan. Anda mungkin perlu menambahkan tipe gips yang eksplisit."
Alex
Versi PostgreSQL apa? Berikut adalah dokumen untuk 9.1: postgresql.org/docs/9.1/static/functions-string.html . Lihat contoh saya: sqlfiddle.com/#!15/d41d8/182
PM 77-1
Anda mungkin memiliki kesalahan sintaksis dalam kueri Anda yang tidak terkait dengan penggabungan.
PM 77-1

Jawaban:

260

Dengan kolom tipe string seperti character(2)(seperti yang Anda sebutkan nanti), rangkaian yang ditampilkan hanya berfungsi karena, mengutip manual:

[...] operator penggabung string ( ||) menerima input non-string, selama setidaknya satu input dari tipe string , seperti yang ditunjukkan pada Tabel 9.8 . Untuk kasus lain, masukkan paksaan eksplisit ke text[...]

Penekanan berani saya. Contoh ke-2 ( select a||', '||b from foo) berfungsi untuk semua tipe data karena string literal yang tidak diketik ', 'default untuk mengetik textmembuat seluruh ekspresi valid dalam kasus apa pun.

Untuk tipe data non-string, Anda dapat "memperbaiki" pernyataan pertama dengan melemparkan setidaknya satu argumen text. ( Semua jenis dapat dilemparkan ke text):

SELECT a::text || b AS ab FROM foo;

Menilai dari jawaban Anda sendiri , " tidak berfungsi " seharusnya berarti " mengembalikan NULL ". Hasil dari apa pun yang digabungkan ke NULL adalah NULL. Jika nilai NULL dapat terlibat dan hasilnya tidak boleh NULL, gunakan concat_ws()untuk menggabungkan sejumlah nilai (Postgres 9.1 atau lebih baru):

SELECT concat_ws(', ', a, b) AS ab FROM foo;

Atau concat()jika Anda tidak membutuhkan pemisah:

SELECT concat(a, b) AS ab FROM foo;

Tidak perlu mengetikkan cor di sini karena kedua fungsi mengambil "any"input dan bekerja dengan representasi teks.

Detail lebih lanjut (dan mengapa COALESCEpengganti yang buruk) dalam jawaban terkait ini:

Mengenai pembaruan dalam komentar

+bukan operator yang valid untuk penggabungan string dalam Postgres (atau SQL standar). Ini adalah ide pribadi Microsoft untuk menambahkan ini ke produk mereka.

Nyaris tidak ada alasan untuk menggunakan character(n)(sinonim:) char(n). Gunakan textatauvarchar . Detail:

Erwin Brandstetter
sumber
Terima kasih. Versi 1 tidak bekerja dengan null dan yang ke-2 memberi saya kesalahan untuk concat_ws: Tidak ada fungsi yang cocok dengan nama dan tipe argumen yang diberikan. Anda mungkin perlu menambahkan gips tipe eksplisit.
Alex
1
Anda memang melihat Postgres 9.1 or later, kan? Anda seharusnya sudah menyediakan versi Postgres Anda, dalam pertanyaan . Harap perbarui pertanyaan Anda dengan semua informasi yang diminta, sebelum Anda kembali untuk hal lain.
Erwin Brandstetter
Terima kasih, solusi yang saya temukan berfungsi untuk semua versi Postgres
Alex
SELECT concat(a, b) FROM foo;bekerja untuk saya di Postgres 9.3 kapan adan bsedang VARCHAR.
hilangkan
Terima kasih atas jawaban Anda, itu menyelesaikan masalah saya :).
ashwaqar
33

Masalahnya adalah dalam nilai nulls; maka Rangkaian tidak bekerja dengan nol. Solusinya adalah sebagai berikut:

SELECT coalesce(a, '') || coalesce(b, '') FROM foo;
Alex
sumber
18

lebih baik menggunakan fungsi CONCAT di PostgreSQL untuk penggabungan

misalnya: select CONCAT(first_name,last_name) from person where pid = 136

jika Anda menggunakan column_a || '' || column_b untuk gabungan 2 kolom, jika salah satu nilai dalam column_a atau column_b adalah null query akan mengembalikan nilai nol. yang mungkin tidak disukai dalam semua kasus .. jadi alih-alih ini

||

menggunakan

CONCAT

itu akan mengembalikan nilai yang relevan jika salah satu dari mereka memiliki nilai

arjun nagathankandy
sumber
7

Fungsi CONCAT terkadang tidak berfungsi dengan versi postgreSQL yang lebih lama

lihat apa yang saya gunakan untuk menyelesaikan masalah tanpa menggunakan CONCAT

 u.first_name || ' ' || u.last_name as user,

Atau bisa juga Anda gunakan

 "first_name" || ' ' || "last_name" as user,

dalam kasus kedua saya menggunakan tanda kutip ganda untuk first_name dan last_name

Semoga ini bermanfaat, terima kasih

Rameshwar Vyevhare
sumber
1
jika nama depan atau nama belakang saya adalah null maka nilai concat juga menunjukkan null
Lokesh
2

Karena saya juga terjebak dalam hal ini, saya pikir saya harus membagikan solusi yang paling cocok untuk saya. Saya juga berpikir bahwa ini jauh lebih sederhana.

Jika Anda menggunakan nama tabel Huruf besar.

SELECT CONCAT("firstName", ' ', "lastName") FROM "User"

Jika Anda menggunakan nama tabel huruf kecil

SELECT CONCAT(firstName, ' ', lastName) FROM user

Itu dia!. Karena PGSQL menghitung Kutipan Ganda untuk deklarasi kolom dan Kutipan Tunggal untuk string, ini berfungsi seperti pesona.

Rakib Uddin
sumber
1

Kerangka kerja Laravel PHP, saya menggunakan search first_name, Last_name Fields anggap seperti Pencarian Nama Lengkap

Menggunakan || simbol Atau metode concat_ws (), concat ()

$names = str_replace(" ", "", $searchKey);                               
$customers = Customer::where('organization_id',$this->user->organization_id)
             ->where(function ($q) use ($searchKey, $names) {
                 $q->orWhere('phone_number', 'ilike', "%{$searchKey}%"); 
                 $q->orWhere('email', 'ilike', "%{$searchKey}%");
                 $q->orWhereRaw('(first_name || last_name) LIKE ? ', '%' . $names. '%');
    })->orderBy('created_at','desc')->paginate(20);

Pesona ini bekerja !!!

venkatskpi
sumber
0

Coba ini

select textcat(textcat(FirstName,' '),LastName) AS Name from person;
Muhammad Sadiq
sumber
8
concat_ws(' ', FirstName, LastName)akan jauh lebih bersih.
a_horse_with_no_name
-1

Misalnya jika ada tabel karyawan yang terdiri dari kolom sebagai:

employee_number,f_name,l_name,email_id,phone_number 

jika kita ingin menyatukan f_name + l_namesebagai name.

SELECT employee_number,f_name ::TEXT ||','|| l_name::TEXT  AS "NAME",email_id,phone_number,designation FROM EMPLOYEE;
Abhishek Mitra
sumber
Apa yang ditambahkan jawaban ini dari jawaban yang ada?
Erwin Brandstetter