Ответ 1
Как правило, я согласен с @kgrittn advice. Пойти на это.
Но чтобы ответить на ваш основной вопрос о concat()
: новая функция concat()
полезна, если вам нужно иметь дело с нулевыми значениями - и в вашем вопросе не исключено ни одно из них. ни в том, на который вы ссылаетесь.
Если вы можете исключить нулевые значения, то старый добрый (стандарт SQL) оператор конкатенации ||
по-прежнему является лучшим выбором, и ответ @luis ' просто прекрасен:
SELECT col_a || col_b;
Если любой из ваших столбцов может быть нулевым, в этом случае результат будет нулевым. Вы можете защищаться с COALESCE
:
SELECT COALESCE(col_a, '') || COALESCE(col_b, '');
Но это быстро становится утомительным с большим количеством аргументов. То, где появляется concat()
, которое никогда не возвращает ноль, даже если все аргументы равны нулю. По документации:
Пустые аргументы игнорируются.
SELECT concat(col_a, col_b);
В оставшемся угловом регистре для обеих альтернатив есть , где все входные столбцы равны нулю, и в этом случае мы все еще получаем пустую строку ''
, но вместо этого может потребоваться пустое значение по крайней мере, я бы). Один из возможных способов:
SELECT CASE
WHEN col_a IS NULL THEN col_b
WHEN col_b IS NULL THEN col_a
ELSE col_a || col_b
END;
Это становится все сложнее с большим количеством столбцов быстро. Снова используйте concat()
, но добавьте проверку для специального условия:
SELECT CASE WHEN (col_a, col_b) IS NULL THEN NULL
ELSE concat(col_a, col_b) END;
Как это работает?
(col_a, col_b)
является сокращенной записью для выражения типа строки ROW (col_a, col_b)
. И тип строки является только нулевым, если все столбцы являются нулевыми. Подробное объяснение:
Также используйте concat_ws()
для добавления разделителей между элементами (ws
для "с разделителем").
Выражение, похожее на ответ кевина:
SELECT $1.zipcode || ' - ' || $1.city || ', ' || $1.state;
утомительно готовить к нулевым значениям в PostgreSQL 8.3 (без concat()
). Один из способов (из многих):
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, '');
Функция волатильности только STABLE
concat()
и concat_ws()
являются функциями STABLE
, а не IMMUTABLE
, поскольку они могут вызывать выходные функции типа данных (например, timestamptz_out
), которые зависят от настроек локали.
Объяснение Тома Лейна.
Это запрещает их прямое использование в выражениях индекса. Если вы знаете, что результат на самом деле является неизменным в вашем случае, вы можете обойти это с помощью оболочки функций IMMUTABLE
. Пример здесь: