varias una posicion nombre modificar especificacion columnas columna cambiar calculada borrar agregar sql postgresql null concatenation

una - especificacion de columna calculada sql server



Combina dos columnas y agrégalas a una nueva columna (3)

¿Revisaste la función de concatenación de cadenas? Algo como:

update table_c set column_a = column_b || column_c

Deberia trabajar. Más here

En PostgreSQL, quiero usar una declaración de SQL para combinar dos columnas y crear una nueva columna de ellas.

Estoy pensando en usar concat(...) , pero ¿hay una mejor manera?
¿Cuál es la mejor manera de hacer esto?


En general, estoy de acuerdo con el consejo de @ kgrittn . Ve a por ello.

Pero para abordar su pregunta básica sobre concat() : la nueva función concat() es útil si necesita tratar con valores nulos , y null no se ha descartado en su pregunta ni en la que se refiere.

Si puede descartar valores nulos, el buen viejo (SQL estándar) operador de concatenación || 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 defenderte con COALESCE :

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

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

Los argumentos NULL son ignorados.

SELECT concat(col_a, col_b);

El caso de 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 posible forma:

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. Nuevamente, use 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;

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

Además, use concat_ws() para agregar separadores entre elementos ( _ws .. "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

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

Esto prohíbe su uso directo en expresiones de índice. Si sabe que el resultado es realmente inmutable en su caso, puede IMMUTABLE con un contenedor de funciones IMMUTABLE . Ejemplo aquí:


No necesita almacenar la columna para referenciarla de esa manera. Prueba esto:

Para configurar:

CREATE TABLE tbl (zipcode text NOT NULL, city text NOT NULL, state text NOT NULL); INSERT INTO tbl VALUES (''10954'', ''Nanuet'', ''NY'');

Podemos ver que tenemos "lo correcto":

/pset border 2 SELECT * FROM tbl;

+---------+--------+-------+ | zipcode | city | state | +---------+--------+-------+ | 10954 | Nanuet | NY | +---------+--------+-------+

Ahora agregue una función con el "nombre de columna" deseado que toma el tipo de registro de la tabla como su único parámetro:

CREATE FUNCTION combined(rec tbl) RETURNS text LANGUAGE SQL AS $$ SELECT $1.zipcode || '' - '' || $1.city || '', '' || $1.state; $$;

Esto crea una función que se puede usar como si fuera una columna de la tabla, siempre que se especifique el nombre o alias de la tabla, así:

SELECT *, tbl.combined FROM tbl;

Que se muestra así:

+---------+--------+-------+--------------------+ | zipcode | city | state | combined | +---------+--------+-------+--------------------+ | 10954 | Nanuet | NY | 10954 - Nanuet, NY | +---------+--------+-------+--------------------+

Esto funciona porque PostgreSQL comprueba primero para una columna real, pero si no se encuentra uno, y el identificador se califica con un nombre de relación o alias, busca una función como la anterior, y la ejecuta con la fila como argumento, regresando el resultado como si fuera una columna. Incluso puede indexar en dicha "columna generada" si desea hacerlo.

Debido a que no está utilizando espacio adicional en cada fila para los datos duplicados, ni disparadores en todas las inserciones y actualizaciones, esto a menudo puede ser más rápido que las alternativas.