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

Kombiner to kolonner og tilføj til en ny kolonne

Generelt er jeg enig i @kgrittns råd. Gå til det.

Men for at løse dit grundlæggende spørgsmål om concat() :Den nye funktion concat() er nyttig, hvis du har brug for at håndtere null-værdier - og null er hverken udelukket i dit spørgsmål eller i det du henviser til.

Hvis du kan udelukke null-værdier, den gode gamle (SQL-standard) sammenkædningsoperator || er stadig det bedste valg, og @luis' svar er helt fint:

SELECT col_a || col_b;

Hvis en af ​​dine kolonner kan være null, resultatet ville være null i så fald. Du kan forsvare med COALESCE :

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

Men det bliver hurtigt kedeligt med flere argumenter. Det er her concat() kommer ind, hvilket aldrig returnerer null, ikke engang hvis alle argumenter er nul. Per dokumentation:

NULL-argumenter ignoreres.

SELECT concat(col_a, col_b);

Den resterende hjørnekasse for begge alternativer er alle inputkolonner er null i så fald får vi stadig en tom streng '' , men man vil måske have null i stedet for (det ville jeg i hvert fald). En mulig måde:

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

Dette bliver hurtigt mere komplekst med flere kolonner. Igen, brug concat() men tilføj en check for den særlige tilstand:

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

Hvordan fungerer dette?
(col_a, col_b) er stenografi for et rækketypeudtryk ROW (col_a, col_b) . Og en rækketype er kun nul, hvis alle kolonner er nul. Detaljeret forklaring:

  • IKKE NULL-begrænsning over et sæt kolonner

Brug også concat_ws() for at tilføje separatorer mellem elementer (ws for "med separator").

Et udtryk som det i Kevins svar:

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

er kedeligt at forberede null-værdier i PostgreSQL 8.3 (uden concat() ). En måde (af mange):

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

Funktionsvolatilitet er kun STABLE

concat() og concat_ws() er STABLE funktioner, ikke IMMUTABLE fordi de kan påkalde datatype output-funktioner (såsom timestamptz_out ), der afhænger af lokalitetsindstillinger.
Forklaring af Tom Lane.

Dette forbyder deres direkte brug i indeksudtryk. Hvis du ved det at resultatet faktisk er uforanderligt i dit tilfælde, kan du omgå dette med en IMMUTABLE funktionsindpakning. Eksempel her:

  • Understøtter PostgreSQL "accentufølsomme" sammenstillinger?


  1. Konverter 'datetimeoffset' til 'datetime2' i SQL Server (T-SQL-eksempler)

  2. ODP.NET Oracle.ManagedDataAccess forårsager ORA-12537 netværkssession slutningen af ​​filen

  3. hvordan rettes OperationalError:(psycopg2.OperationalError) server lukkede forbindelsen uventet

  4. Entity Framework 6 - Timing forespørgsler