sql >> Base de Datos >  >> RDS >> PostgreSQL

Combinar dos columnas y agregar en una nueva columna

En general, estoy de acuerdo con el consejo de @kgrittn. Anímate.

Pero para abordar su pregunta básica sobre concat() :La nueva función concat() es útil si necesita lidiar con valores nulos - y no se ha descartado nulo en tu pregunta ni en la que te refieres.

Si puede descartar valores nulos, el viejo operador de concatenación (estándar SQL) || sigue siendo la mejor opción, y la respuesta de @luis está bien:

SELECT col_a || col_b;

Si cualquiera de sus columnas puede ser nula, el resultado sería nulo en ese caso. Podrías defender con COALESCE :

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

Pero eso se vuelve tedioso rápidamente con más argumentos. Ahí es donde concat() entra, que nunca devuelve nulo, ni siquiera si todos los argumentos son nulos. Por documentación:

Los argumentos NULL se ignoran.

SELECT concat(col_a, col_b);

El caso de la esquina restante para ambas alternativas es donde todas las columnas de entrada son nulas en cuyo caso todavía obtenemos una cadena vacía '' , pero uno podría querer nulo en su lugar (al menos yo lo haría). Una forma posible:

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

Esto se vuelve más complejo con más columnas rápidamente. De nuevo, usa concat() pero agregue un cheque para la condición especial:

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

¿Cómo funciona esto?
(col_a, col_b) es una notación abreviada para una expresión de tipo fila ROW (col_a, col_b) . Y un tipo de fila solo es nulo si todos las columnas son nulas. Explicación detallada:

  • Restricción NOT NULL sobre un conjunto de columnas

Además, use concat_ws() para agregar separadores entre elementos (ws para "con separador").

Una expresión como la de la respuesta de Kevin:

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

es tedioso prepararse para valores nulos en PostgreSQL 8.3 (sin concat() ). Una forma (de muchas):

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 volatilidad de la función es solo STABLE

concat() y concat_ws() son STABLE funciones, no IMMUTABLE porque pueden invocar funciones de salida de tipos de datos (como timestamptz_out ) que dependen de la configuración regional.
Explicación de Tom Lane.

Esto prohíbe su uso directo en expresiones de índice. Si sabes que el resultado es realmente inmutable en su caso, puede solucionar esto con un IMMUTABLE envoltorio de función. Ejemplo aquí:

  • ¿PostgreSQL admite intercalaciones "insensibles a los acentos"?