Im Allgemeinen stimme ich dem Rat von @kgrittn zu. Mach es.
Aber um Ihre grundlegende Frage zu concat()
zu beantworten :Die neue Funktion concat()
ist nützlich, wenn Sie mit Nullwerten umgehen müssen - und null wurde weder in Ihrer Frage noch in der Frage, auf die Sie sich beziehen, ausgeschlossen.
Wenn Sie können Nullwerte ausschließen, den guten alten (SQL-Standard) Verkettungsoperator ||
ist immer noch die beste Wahl, und die Antwort von @luis ist in Ordnung:
SELECT col_a || col_b;
Wenn Jede Ihrer Spalten kann null sein, das Ergebnis wäre in diesem Fall null. Sie könnten sich mit COALESCE
verteidigen :
SELECT COALESCE(col_a, '') || COALESCE(col_b, '');
Aber das wird mit mehr Argumenten schnell langweilig. Dort ist concat()
reinkommt, was nie gibt null zurück, nicht einmal wenn all Argumente sind null. Per Dokumentation:
NULL-Argumente werden ignoriert.
SELECT concat(col_a, col_b);
Der verbleibende Eckfall für beide Alternativen ist all Eingabespalten sind null In diesem Fall erhalten wir immer noch eine leere Zeichenfolge ''
, aber man könnte stattdessen null wollen (zumindest würde ich). Ein möglicher Weg:
SELECT CASE
WHEN col_a IS NULL THEN col_b
WHEN col_b IS NULL THEN col_a
ELSE col_a || col_b
END;
Das wird mit mehr Spalten schnell komplexer. Verwenden Sie wieder concat()
aber fügen Sie ein Häkchen für die spezielle Bedingung hinzu:
SELECT CASE WHEN (col_a, col_b) IS NULL THEN NULL
ELSE concat(col_a, col_b) END;
Wie funktioniert das? (col_a, col_b)
ist eine Kurzschreibweise für einen Zeilentypausdruck ROW (col_a, col_b)
. Und ein Zeilentyp ist nur null, wenn alle Spalten sind null. Ausführliche Erklärung:
- NOT NULL-Einschränkung über eine Reihe von Spalten
Verwenden Sie außerdem concat_ws()
um Trennzeichen zwischen Elementen hinzuzufügen (ws
für "mit Trennzeichen").
Ein Ausdruck wie in Kevins Antwort:
SELECT $1.zipcode || ' - ' || $1.city || ', ' || $1.state;
Es ist mühsam, sich in PostgreSQL 8.3 (ohne concat()
) auf Nullwerte vorzubereiten ). Ein Weg (von vielen):
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, '');
Funktionsvolatilität ist nur STABLE
concat()
und concat_ws()
sind STABLE
Funktionen, nicht IMMUTABLE
weil sie Datentyp-Ausgabefunktionen aufrufen können (wie timestamptz_out
), die von den Locale-Einstellungen abhängen.
Erklärung von Tom Lane.
Dies verbietet ihre direkte Verwendung in Indexausdrücken. Wenn Sie wissen dass das Ergebnis in Ihrem Fall tatsächlich unveränderlich ist, können Sie dies mit einem IMMUTABLE
umgehen Funktions-Wrapper. Beispiel hier:
- Unterstützt PostgreSQL "akzentunabhängige" Sortierungen?