PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Combina due colonne e aggiungi in una nuova colonna

In generale, sono d'accordo con il consiglio di @kgrittn. Provaci.

Ma per rispondere alla tua domanda di base su concat() :La nuova funzione concat() è utile se devi gestire valori nulli - e nullo non è stato escluso né nella tua domanda né in quella a cui ti riferisci.

Se puoi escludere valori nulli, il buon vecchio operatore di concatenazione (standard SQL) || è ancora la scelta migliore e la risposta di @luis va bene:

SELECT col_a || col_b;

Se una delle tue colonne può essere nulla, il risultato sarebbe nullo in quel caso. Potresti difenderti con COALESCE :

SELECT COALESCE(col_a, '') || COALESCE(col_b, '');

Ma questo diventa noioso rapidamente con più argomenti. Ecco dove concat() entra, cosa che mai restituisce null, nemmeno se tutti gli argomenti sono nulli. Per documentazione:

Gli argomenti NULL vengono ignorati.

SELECT concat(col_a, col_b);

Il caso d'angolo rimanente per entrambe le alternative è dove tutti le colonne di input sono null in tal caso otteniamo ancora una stringa vuota '' , ma si potrebbe invece volere null (almeno lo farei). Un modo possibile:

SELECT CASE
          WHEN col_a IS NULL THEN col_b
          WHEN col_b IS NULL THEN col_a
          ELSE col_a || col_b
       END;

Questo diventa più complesso con più colonne rapidamente. Ancora una volta, usa concat() ma aggiungi un segno di spunta per la condizione speciale:

SELECT CASE WHEN (col_a, col_b) IS NULL THEN NULL
            ELSE concat(col_a, col_b) END;

Come funziona?
(col_a, col_b) è una notazione abbreviata per un'espressione di tipo riga ROW (col_a, col_b) . E un tipo di riga è nullo solo se tutti le colonne sono nulle. Spiegazione dettagliata:

  • vincolo NOT NULL su un insieme di colonne

Inoltre, usa concat_ws() per aggiungere separatori tra gli elementi (ws per "con separatore").

Un'espressione come quella nella risposta di Kevin:

SELECT $1.zipcode || ' - ' || $1.city || ', ' || $1.state;

è noioso preparare i valori null in PostgreSQL 8.3 (senza concat() ). Un modo (di molti):

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, '');

La volatilità delle funzioni è solo STABLE

concat() e concat_ws() sono STABLE funzioni, non IMMUTABLE perché possono invocare funzioni di output del tipo di dati (come timestamptz_out ) che dipendono dalle impostazioni locali.
Spiegazione di Tom Lane.

Ciò ne vieta l'uso diretto nelle espressioni di indice. Se sai che il risultato sia effettivamente immutabile nel tuo caso, puoi aggirare il problema con un IMMUTABLE involucro di funzioni. Esempio qui:

  • PostgreSQL supporta le regole di confronto "insensibili all'accento"?