Actualizar o insertar (varias filas y columnas) desde una subconsulta en PostgreSQL

106

Estoy tratando de hacer algo como esto en postgres:

  • UPDATE table1 SET (col1, col2) = (SELECT col2, col3 FROM othertable WHERE othertable.col1 = 123);

  • INSERT INTO table1 (col1, col2) VALUES (SELECT col1, col2 FROM othertable)

Pero el punto 1 no es posible incluso con postgres 9.0 como se menciona en los documentos ( http://www.postgresql.org/docs/9.0/static/sql-update.html )

Además, el punto 2 parece no funcionar. Recibo el siguiente error: la subconsulta debe devolver solo una columna.

Espero que alguien tenga una solución para mí. de lo contrario, las consultas tomarán mucho tiempo :(.

FYI: Estoy tratando de seleccionar diferentes columnas de varias tablas y almacenarlas en una tabla temporal, para que otra aplicación pueda recuperar fácilmente los datos preparados.

dforce
fuente

Respuestas:

175

Para la ACTUALIZACIÓN

Utilizar:

UPDATE table1 
   SET col1 = othertable.col2,
       col2 = othertable.col3 
  FROM othertable 
 WHERE othertable.col1 = 123;

Para el INSERT

Utilizar:

INSERT INTO table1 (col1, col2) 
SELECT col1, col2 
  FROM othertable

No necesita la VALUESsintaxis si está utilizando un SELECT para completar los valores INSERT.

Ponis dios mio
fuente
1
¿Es posible combinar Actualizar e Insertar para que si uno falla, el otro se use sin arrojar un error (independientemente para cada fila)? Creo que sería una solución más completa a la pregunta (por ejemplo: stackoverflow.com/a/6527838/781695 )
usuario
26

La respuesta de OMG Ponies funciona perfectamente, pero en caso de que necesite algo más complejo, aquí hay un ejemplo de una consulta de actualización un poco más avanzada:

UPDATE table1 
SET col1 = subquery.col2,
    col2 = subquery.col3 
FROM (
    SELECT t2.foo as col1, t3.bar as col2, t3.foobar as col3 
    FROM table2 t2 INNER JOIN table3 t3 ON t2.id = t3.t2_id
    WHERE t2.created_at > '2016-01-01'
) AS subquery
WHERE table1.id = subquery.col1;
David Namenyi
fuente
1
Eres el mejor :) :)
Ashwini
1
Perfecto. esto funciona mejor cuando necesita elegir un subconjunto basado en una condición que involucra la tabla actualizada.
mythicalcoder
@David Namenyi ¿puedes explicar esta consulta?
Chintan Pathak
15
UPDATE table1 SET (col1, col2) = (col2, col3) FROM othertable WHERE othertable.col1 = 123;
Walter
fuente