Obecně souhlasím s radou @kgrittn. Jděte do toho.
Ale abych odpověděl na vaši základní otázku o concat()
:Nová funkce concat()
je užitečné, pokud se potřebujete vypořádat s nulovými hodnotami - a null nebylo vyloučeno ani ve vaší otázce, ani v té, na kterou odkazujete.
Pokud můžete vyloučit hodnoty null, starý dobrý operátor zřetězení (standard SQL) ||
je stále nejlepší volbou a odpověď @luis je v pořádku:
SELECT col_a || col_b;
Pokud kterýkoli z vašich sloupců může být null, v takovém případě by byl výsledek null. Můžete se bránit pomocí COALESCE
:
SELECT COALESCE(col_a, '') || COALESCE(col_b, '');
Ale to bude s dalšími argumenty rychle únavné. To je místo concat()
přichází, což nikdy vrátí hodnotu null, i když vše argumenty jsou nulové. Podle dokumentace:
Argumenty NULL jsou ignorovány.
SELECT concat(col_a, col_b);
Zbývající rohové pouzdro pro obě alternativy je kde vše vstupní sloupce jsou null v takovém případě stále dostáváme prázdný řetězec ''
, ale někdo by místo toho mohl chtít null (alespoň já). Jeden možný způsob:
SELECT CASE
WHEN col_a IS NULL THEN col_b
WHEN col_b IS NULL THEN col_a
ELSE col_a || col_b
END;
S více sloupci se to stává složitější. Opět použijte concat()
ale přidejte šek na zvláštní podmínku:
SELECT CASE WHEN (col_a, col_b) IS NULL THEN NULL
ELSE concat(col_a, col_b) END;
Jak to funguje? (col_a, col_b)
je zkrácený zápis pro výraz typu řádku ROW (col_a, col_b)
. A typ řádku je null pouze v případě, že vše sloupce jsou prázdné. Podrobné vysvětlení:
- NOT NULL omezení pro sadu sloupců
Použijte také concat_ws()
pro přidání oddělovačů mezi prvky (ws
pro "s oddělovačem").
Výraz jako ten v Kevinově odpovědi:
SELECT $1.zipcode || ' - ' || $1.city || ', ' || $1.state;
je únavné se připravit na hodnoty null v PostgreSQL 8.3 (bez concat()
). Jeden způsob (z mnoha):
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, '');
Nestálost funkcí je pouze STABLE
concat()
a concat_ws()
jsou STABLE
funkce, nikoli IMMUTABLE
protože mohou vyvolat výstupní funkce datového typu (jako timestamptz_out
), které závisí na nastavení národního prostředí.
Vysvětlení Tom Lane.
To zakazuje jejich přímé použití v indexových výrazech. Pokud víte že výsledek je ve vašem případě skutečně neměnný, můžete to obejít pomocí IMMUTABLE
funkční obal. Příklad zde:
- Podporuje PostgreSQL kolace „necitlivá na akcent“?