Generellt håller jag med om @kgrittns råd. Gör det.
Men för att ta itu med din grundläggande fråga om concat()
:Den nya funktionen concat()
är användbart om du behöver hantera nullvärden - och null har varken uteslutits i din fråga eller i den du refererar till.
Om du kan utesluta nollvärden, den gamla goda (SQL-standard) sammanfogningsoperatorn ||
är fortfarande det bästa valet, och @luis svar är bara bra:
SELECT col_a || col_b;
Om någon av dina kolumner kan vara null, resultatet skulle vara null i så fall. Du kan försvara med COALESCE
:
SELECT COALESCE(col_a, '') || COALESCE(col_b, '');
Men det blir snabbt tråkigt med fler argument. Det är där concat()
kommer in, vilket aldrig returnerar null, inte ens om alla argumenten är ogiltiga. Per dokumentation:
NULL-argument ignoreras.
SELECT concat(col_a, col_b);
Det återstående hörnfodralet för båda alternativen är alla indatakolumner är null i så fall får vi fortfarande en tom sträng ''
, men man kanske vill ha null istället (åtminstone jag skulle). Ett möjligt sätt:
SELECT CASE
WHEN col_a IS NULL THEN col_b
WHEN col_b IS NULL THEN col_a
ELSE col_a || col_b
END;
Detta blir mer komplext med fler kolumner snabbt. Återigen, använd concat()
men lägg till en check för specialvillkoret:
SELECT CASE WHEN (col_a, col_b) IS NULL THEN NULL
ELSE concat(col_a, col_b) END;
Hur fungerar det här? (col_a, col_b)
är förkortad notation för ett radtypsuttryck ROW (col_a, col_b)
. Och en radtyp är bara null om alla kolumner är null. Detaljerad förklaring:
- INTE NULL-begränsning över en uppsättning kolumner
Använd även concat_ws()
för att lägga till avgränsare mellan element (ws
för "med separator").
Ett uttryck som det i Kevins svar:
SELECT $1.zipcode || ' - ' || $1.city || ', ' || $1.state;
är tråkigt att förbereda sig för nullvärden i PostgreSQL 8.3 (utan concat()
). Ett sätt (av många):
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, '');
Funktionsvolatiliteten är endast STABLE
concat()
och concat_ws()
är STABLE
funktioner, inte IMMUTABLE
eftersom de kan anropa datatyputgångsfunktioner (som timestamptz_out
) som beror på språkinställningar.
Förklaring av Tom Lane.
Detta förbjuder deras direkta användning i indexuttryck. Om du vet att resultatet faktiskt är oföränderligt i ditt fall, kan du kringgå detta med en IMMUTABLE
funktionsomslag. Exempel här:
- Stöder PostgreSQL "accentokänsliga" sammanställningar?