PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Kombinieren Sie zwei Spalten und fügen Sie sie zu einer neuen Spalte hinzu

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?