sql >> Databáze >  >> RDS >> PostgreSQL

Spojte dva sloupce a přidejte je do jednoho nového sloupce

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


  1. MariaDB DATABASE() Vysvětleno

  2. Jak migrovat z Oracle DB na MariaDB

  3. Jak vybrat poslední záznam tabulky v SQL?

  4. Příkaz SQL UPDATE pro přepnutí dvou hodnot ve dvou řádcích