Как объединить столбцы в Postgres 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)
,
9 ответов
Проблема была в нулях в значениях; тогда конкатенация не работает с нулями. Решение заключается в следующем:
SELECT coalesce(a, '') || coalesce(b, '') FROM foo;
Со столбцами типа строки 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
, Подробности:
Для конкатенации лучше использовать функцию CONCAT в PostgreSQL
например: select CONCAT(first_name,last_name) from person where pid = 136
если вы используете column_a || ' ' || column_b для конкатенации для 2-х столбцов, если любое из значений в column_a или column_b равно нулю, запрос вернет нулевое значение. что не может быть предпочтительным во всех случаях.. поэтому вместо этого
||
использование
CONCAT
он вернет соответствующее значение, если любой из них имеет значение
Поскольку я тоже застрял в этом, думаю, мне стоит поделиться решением, которое лучше всего сработало для меня. Я тоже считаю, что это намного проще.
Если вы используете имя таблицы с заглавной буквы.
SELECT CONCAT("firstName", ' ', "lastName") FROM "User"
Если вы используете имя таблицы в нижнем регистре
SELECT CONCAT(firstName, ' ', lastName) FROM user
Это оно!. Поскольку PGSQL считает двойные кавычки для объявления столбца и одинарные кавычки для строки, это работает как шарм.
Функции CONCAT иногда не работают со старой версией postgreSQL
посмотрите, что я использовал для решения проблемы без использования CONCAT
u.first_name || ' ' || u.last_name as user,
Или также вы можете использовать
"first_name" || ' ' || "last_name" as user,
во втором случае я использовал двойные кавычки для имени и фамилии
Надеюсь, это будет полезно, спасибо
PHP каркас Laravel,я использую поиск first_name, last_name Поля считают похожими на поиск полного имени
Использование || символ или методы 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);
Это сработало очарование!!!
Например, если есть таблица сотрудников, которая состоит из столбцов в виде:
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;
Попробуй это
select textcat(textcat(FirstName,' '),LastName) AS Name from person;
Для этой операции также можно использовать трубу.
Select EmployeeID ,FirstName ||' ' || LastName as Full_Name from Employees
order by EmployeeID