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"?