Как конкатенация столбцов в столбце SELECT?

У меня есть два строковых столбца a и b в таблице foo.

select a, b from foo возвращает значения a и b. Однако объединение a и b не работает. Я пытался:

select a || b from foo

и

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

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

Ответ 1

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

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

Ответ 2

С строковыми столбцами типа, такими как character(2) (как вы упоминали позже), отображаемая конкатенация работает только потому, что, цитируя руководство:

[...] оператор конкатенации строк (||) принимает не-строки input, если хотя бы один вход имеет строковый тип, как показано на Таблица 9.8. В других случаях вставьте явное приведение к text [...]

Жирный акцент мой. Второй пример (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. Подробности:

Ответ 3

лучше использовать функцию CONCAT в PostgreSQL для конкатенации

например: select CONCAT(first_name,last_name) from person where pid = 136

если вы используете column_a || '' || column_b для конкатенации для 2 столбцов, если какое-либо из значений в столбце_a или column_b является нулевым запросом, вернет нулевое значение. который не может быть предпочтительным во всех случаях. Поэтому вместо этого

||

использовать

CONCAT

он вернет соответствующее значение, если любое из них имеет значение

Ответ 4

Функции CONCAT иногда не работают со старой версией postgreSQL

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

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

Или вы также можете использовать

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

во втором случае я использовал двойные кавычки для first_name и last_name

Надеюсь, это будет полезно, спасибо

Ответ 5

Попробуйте это

select textcat(textcat(FirstName,' '),LastName) AS Name from person;

Ответ 6

PHP Laravel Framework, Я использую поиск first_name, last_name Поля считают похожими на поиск полного имени

Using || symbol Or concat_ws(), concat() methods

$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);

Это сработало очарование !!!

Ответ 7

Например, если есть таблица сотрудников, которая состоит из столбцов:

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;