La pregunta es antigua pero sentí que la mejor respuesta aún no se había dado.
¿Hay una UPDATE
sintaxis ... sin especificar los nombres de columna ?
Solución general con SQL dinámico
No necesita saber ningún nombre de columna, excepto algunas columnas únicas para unirse ( id
en el ejemplo). Funciona de manera confiable para cualquier posible caso de esquina que se me ocurra.
Esto es específico de PostgreSQL. Estoy construyendo código dinámico basado en el esquema de información , en particular la tabla information_schema.columns
, que se define en el estándar SQL y la mayoría de los RDBMS principales (excepto Oracle) lo tienen. Pero una DO
declaración con código PL / pgSQL que ejecuta SQL dinámico es una sintaxis PostgreSQL totalmente no estándar.
DO
$do$
BEGIN
EXECUTE (
SELECT
'UPDATE b
SET (' || string_agg( quote_ident(column_name), ',') || ')
= (' || string_agg('a.' || quote_ident(column_name), ',') || ')
FROM a
WHERE b.id = 123
AND a.id = b.id'
FROM information_schema.columns
WHERE table_name = 'a' -- table name, case sensitive
AND table_schema = 'public' -- schema name, case sensitive
AND column_name <> 'id' -- all columns except id
);
END
$do$;
Asumiendo una columna coincidente b
para cada columna a
, pero no al revés. b
puede tener columnas adicionales.
WHERE b.id = 123
es opcional, para actualizar una fila seleccionada.
SQL Fiddle.
Respuestas relacionadas con más explicaciones:
Soluciones parciales con SQL simple
Con lista de columnas compartidas
Aún necesita conocer la lista de nombres de columna que comparten ambas tablas. Con un acceso directo de sintaxis para actualizar varias columnas, más corto que lo que otras respuestas sugirieron hasta ahora en cualquier caso.
UPDATE b
SET ( column1, column2, column3)
= (a.column1, a.column2, a.column3)
FROM a
WHERE b.id = 123 -- optional, to update only selected row
AND a.id = b.id;
SQL Fiddle.
Esta sintaxis se introdujo con Postgres 8.2 en 2006, mucho antes de que se hiciera la pregunta. Detalles en el manual.
Relacionado:
Con lista de columnas en B
Si todas las columnas de A
están definidos NOT NULL
(pero no necesariamente B
),
y se conocen los nombres de las columnas de B
(pero no necesariamente A
).
UPDATE b
SET (column1, column2, column3, column4)
= (COALESCE(ab.column1, b.column1)
, COALESCE(ab.column2, b.column2)
, COALESCE(ab.column3, b.column3)
, COALESCE(ab.column4, b.column4)
)
FROM (
SELECT *
FROM a
NATURAL LEFT JOIN b -- append missing columns
WHERE b.id IS NULL -- only if anything actually changes
AND a.id = 123 -- optional, to update only selected row
) ab
WHERE b.id = ab.id;
Se NATURAL LEFT JOIN
une a una fila desde b
donde todas las columnas del mismo nombre contienen los mismos valores. No necesitamos una actualización en este caso (nada cambia) y podemos eliminar esas filas al principio del proceso ( WHERE b.id IS NULL
).
Todavía necesitamos encontrar una fila coincidente, así que b.id = ab.id
en la consulta externa.
db <> violín aquí
Viejo sqlfiddle.
Este es SQL estándar, excepto por la FROM
cláusula .
Funciona sin importar en qué columnas estén realmente presentes A
, pero la consulta no puede distinguir entre valores NULL reales y columnas faltantes A
, por lo que solo es confiable si todas las columnas A
están definidas NOT NULL
.
Existen múltiples variaciones posibles, según lo que sepa sobre ambas tablas.