PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Combinez deux colonnes et ajoutez-les dans une nouvelle colonne

Généralement, je suis d'accord avec les conseils de @kgrittn. Allez-y.

Mais pour répondre à votre question de base sur concat() :La nouvelle fonction concat() est utile si vous devez gérer des valeurs nulles - et null n'a été exclu ni dans votre question ni dans celle à laquelle vous faites référence.

Si vous pouvez exclure les valeurs nulles, le bon vieil opérateur de concaténation (standard SQL) || est toujours le meilleur choix, et la réponse de @luis est très bien :

SELECT col_a || col_b;

Si l'une ou l'autre de vos colonnes peut être nulle, le résultat serait nul dans ce cas. Vous pourriez défendre avec COALESCE :

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

Mais cela devient rapidement fastidieux avec plus d'arguments. C'est là que concat() arrive, ce qui jamais renvoie null, pas même si tous les arguments sont nuls. Par documentation :

Les arguments NULL sont ignorés.

SELECT concat(col_a, col_b);

Le cas d'angle restant pour les deux alternatives est où tous les colonnes d'entrée sont nulles auquel cas nous obtenons toujours une chaîne vide '' , mais on pourrait vouloir null à la place (du moins je le ferais). Une manière possible :

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

Cela devient plus complexe avec plus de colonnes rapidement. Encore une fois, utilisez concat() mais ajoutez une vérification pour la condition spéciale :

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

Comment ça marche ?
(col_a, col_b) est une notation abrégée pour une expression de type ligne ROW (col_a, col_b) . Et un type de ligne n'est nul que si tous les colonnes sont nulles. Explication détaillée :

  • Contrainte NOT NULL sur un ensemble de colonnes

Utilisez également concat_ws() pour ajouter des séparateurs entre les éléments (ws pour "avec séparateur").

Une expression comme celle de la réponse de Kevin :

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

est fastidieux de se préparer aux valeurs nulles dans PostgreSQL 8.3 (sans concat() ). Une manière (parmi plusieurs) :

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é de la fonction est uniquement STABLE

concat() et concat_ws() sont STABLE fonctions, pas IMMUTABLE car ils peuvent invoquer des fonctions de sortie de type de données (comme timestamptz_out ) qui dépendent des paramètres régionaux.
Explication par Tom Lane.

Cela interdit leur utilisation directe dans les expressions d'index. Si vous savez que le résultat est en fait immuable dans votre cas, vous pouvez contourner ce problème avec un IMMUTABLE enveloppe de fonction. Exemple ici :

  • PostgreSQL prend-il en charge les classements "insensibles aux accents" ?