Як об'єднати стовпці в SELECT Postgres?


145

У мене є два стовпці рядків aі bв таблиці foo.

select a, b from fooповертає значення aі b. Однак конкатенація aі bне працює. Я намагався :

select a || b from foo

і

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

Оновлення з коментарів: обидва стовпці мають тип character(2).


... чи іншого textтипу?
PM 77-1

@acfrancis Оскільки ОП каже, concatenateя сумніваюся, що він має справу з числовими типами, хоча PostgreSQL також піклується про деякі з них. Дивіться тут: postgresql.org/docs/9.1/static/functions-string.html
PM 77-1

Так, ці стовпці мають характер (2). "+" не працює - "Жоден оператор не відповідає вказаному імені та типам аргументів. Можливо, вам доведеться додати явні типи типів."
Олексій

Яка версія PostgreSQL? Ось документи для версії 9.1: postgresql.org/docs/9.1/static/functions-string.html . Дивіться мій приклад: sqlfiddle.com/#!15/d41d8/182
PM 77-1

Можливо, у вашому запиті є синтаксична помилка, не пов’язана з конкатенацією.
PM 77-1

Відповіді:


260

У стовпцях типу рядка типуcharacter(2) (як ви згадували пізніше) відображене конкатенація просто працює, оскільки, цитуючи посібник:

[...] оператор конкатенації рядків ( ||) приймає нестроковий вхід, якщо принаймні один вхід має рядковий тип , як показано в таблиці 9.8 . Для інших випадків введіть явний примус до text[...]

Сміливий акцент мій. 2-й приклад ( select a||', '||b from foo) працює для будь-яких типів даних, оскільки типовий рядковий рядковий буквально ', 'за замовчуванням вводить, textроблячи весь вираз дійсним у будь-якому випадку.

Для нестрокових типів даних ви можете "виправити" 1-е твердження, передавши принаймні один аргумент text. ( Будь-який тип може бути переданий text):

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

Судячи з вашої власної відповіді , " не працює " повинно було означати " повертає NULL ". Результатом будь-якого об'єднаного в NULL є NULL. Якщо можуть бути залучені значення NULL, а результат не повинен бути NULL, використовуйте concat_ws()для об'єднання будь-якої кількості значень (Postgres 9.1 або новіших версій):

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

Або concat()якщо вам не потрібні роздільники:

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

Тут немає потреби в типових кастингах, оскільки обидві функції приймають "any"введення та працюють із текстовими поданнями.

Більш детально (і чому COALESCEце погана заміна) у цій відповіді:

Щодо оновлення в коментарі

+не є дійсним оператором для об'єднання рядків у Postgres (або стандартному SQL). Приватна ідея Microsoft додати це до своїх продуктів.

Навряд чи є якась вагома причина для використання character(n)(синонім:) char(n). Використовуйте textабоvarchar . Деталі:


Дякую. 1-я версія не працює з null, а 2-я дала мені помилку concat_ws: жодна функція не відповідає заданому типу імен та аргументів. Можливо, вам доведеться додати явні типи ролі.
Олексій

1
Ви бачили Postgres 9.1 or later, правда? Ви повинні надати свою версію Postgres для початку у питанні . Будь ласка, оновіть своє запитання всією запитаною інформацією, перш ніж ви повернетесь за чим-небудь іншим.
Ервін Брандстеттер

Дякую, що я знайшов рішення для будь-якої версії Postgres
Алекс

SELECT concat(a, b) FROM foo;працює для мене в Postgres 9.3, коли aі bє VARCHARs.
ліквідувати

Дякую за вашу відповідь, це вирішило мою проблему :).
ашваквар

33

Проблема полягала в нулях у значеннях; то конкатенація не працює з нулями. Рішення полягає в наступному:

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

18

для конкатенації краще використовувати функцію CONCAT в PostgreSQL

наприклад: select CONCAT(first_name,last_name) from person where pid = 136

якщо ви використовуєте column_a || '' || column_b для конкатенації для 2 стовпця, якщо будь-яке значення у column_a або column_b є нульовим запитом, поверне нульове значення. що може бути не кращим у всіх випадках .. тому замість цього

||

використання

КОНЦАТ

воно поверне відповідне значення, якщо будь-який з них має значення


7

Функції CONCAT іноді не працюють зі старшою версією postgreSQL

подивіться, що я використовував для вирішення проблеми без використання CONCAT

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

Або також можна використовувати

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

у другому випадку я використав подвійні лапки для імені та прізвища

Сподіваюся, це буде корисно, дякую


1
якщо моє ім’я або прізвище є нульовим, то значення "concat" також відображається з нуля
Lokesh

2

Оскільки я також застряг у цьому, подумайте, що мені слід поділитися рішенням, яке найкраще працювало для мене. Я також вважаю, що це набагато простіше.

Якщо ви використовуєте назву таблиці з великої літери.

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

Якщо ви використовуєте малу назву таблиці

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

Це воно!. Оскільки PGSQL вважає подвійну котировку для декларації стовпців та Одиночну цитату для рядка, це працює як шарм.


1

PHP-рамка Laravel, я використовую пошук ім'я-ім’я, прізвище Поля вважаються як пошук повного імені

Використання || символ або 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);

Це спрацювало чарівність !!!



-1

Наприклад, якщо є таблиця працівників, яка складається з стовпців:

employee_number,f_name,l_name,email_id,phone_number 

якщо ми хочемо об'єднатися f_name + l_nameяк name.

SELECT employee_number,f_name ::TEXT ||','|| l_name::TEXT  AS "NAME",email_id,phone_number,designation FROM EMPLOYEE;

Що ця відповідь додає до наявних відповідей?
Erwin Brandstetter
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.