with update postgres inner from example con postgresql syntax

inner - update from select postgresql



¿Cómo hacer una actualización+unirse a PostgreSQL? (6)

Aquí hay un SQL simple que actualiza Mid_Name en la tabla de Name3 usando el campo Middle_Name de Name:

update name3 set mid_name = name.middle_name from name where name3.person_id = name.person_id;

Básicamente, quiero hacer esto:

update vehicles_vehicle v join shipments_shipment s on v.shipment_id=s.id set v.price=s.price_per_vehicle;

Estoy bastante seguro de que funcionaría en MySQL (mi fondo), pero parece que no funciona en postgres. El error que recibo es:

ERROR: syntax error at or near "join" LINE 1: update vehicles_vehicle v join shipments_shipment s on v.shi... ^

Seguramente hay una forma fácil de hacer esto, pero no puedo encontrar la sintaxis correcta. Entonces, ¿cómo escribiría esto en PostgreSQL?


Aquí vamos:

update vehicles_vehicle v set price=s.price_per_vehicle from shipments_shipment s where v.shipment_id=s.id;

Tan simple como pude hacerlo. ¡Gracias chicos!

También puede hacer esto:

update vehicles_vehicle set price=s.price_per_vehicle from vehicles_vehicle v join shipments_shipment s on v.shipment_id=s.id;

Pero luego tienes la tabla de vehículos allí dos veces, y solo puedes aliasla una vez, y no puedes usar el alias en la parte "conjunto".


Déjame explicarte un poco más con mi ejemplo.

Tarea: información correcta, donde los abiturientes (estudiantes que están a punto de abandonar la escuela secundaria) han presentado solicitudes a la universidad antes de que obtuvieran los certificados escolares (sí, obtuvieron los certificados antes de lo que fueron emitidos (por fecha de certificado especificada). aumentar la fecha de envío de la solicitud para que se ajuste a la fecha de emisión del certificado.

Así. siguiente declaración de MySQL:

UPDATE applications a JOIN ( SELECT ap.id, ab.certificate_issued_at FROM abiturients ab JOIN applications ap ON ab.id = ap.abiturient_id WHERE ap.documents_taken_at::date < ab.certificate_issued_at ) b ON a.id = b.id SET a.documents_taken_at = b.certificate_issued_at;

Se convierte en similar a PostgreSQL de tal manera

UPDATE applications a SET documents_taken_at = b.certificate_issued_at -- we can reference joined table here FROM abiturients b -- joined table WHERE a.abiturient_id = b.id AND -- JOIN ON clause a.documents_taken_at::date < b.certificate_issued_at -- Subquery WHERE

Como puede ver, la cláusula ON subconsulta original se ha convertido en una de las condiciones WHERE , que se conjuga con AND con otras, que se han trasladado de la subconsulta sin cambios. Y ya no hay necesidad de JOIN tabla consigo misma (como estaba en la subconsulta).


La sintaxis de UPDATE es:

[ WITH [ RECURSIVE ] with_query [, ...] ] UPDATE [ ONLY ] table [ [ AS ] alias ] SET { column = { expression | DEFAULT } | ( column [, ...] ) = ( { expression | DEFAULT } [, ...] ) } [, ...] [ FROM from_list ] [ WHERE condition | WHERE CURRENT OF cursor_name ] [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]

En tu caso creo que quieres esto:

UPDATE vehicles_vehicle AS v SET price = s.price_per_vehicle FROM shipments_shipment AS s WHERE v.shipment_id = s.id


La respuesta de Mark Byers es la óptima en esta situación. Aunque en situaciones más complejas, puede tomar la consulta de selección que devuelve filas y valores calculados y adjuntarla a la consulta de actualización de esta manera:

with t as ( -- Any generic query which returns rowid and corresponding calculated values select t1.id as rowid, f(t2, t2) as calculatedvalue from table1 as t1 join table2 as t2 on t2.referenceid = t1.id ) update t1 set value = t.calculatedvalue from t where id = t.rowid

Este enfoque le permite desarrollar y probar su consulta de selección y, en dos pasos, convertirla en la consulta de actualización.

Así que en tu caso la consulta de resultados será:

with t as ( select v.id as rowid, s.price_per_vehicle as calculatedvalue from vehicles_vehicle v join shipments_shipment s on v.shipment_id = s.id ) update vehicles_vehicle set price = t.calculatedvalue from t where id = t.rowid

Tenga en cuenta que los alias de columna son obligatorios, de lo contrario, PostgreSQL se quejará de la ambigüedad de los nombres de columna.


Para aquellos que realmente quieran hacer una JOIN también puedes usar:

UPDATE a SET price = b_alias.unit_price FROM a as a_alias LEFT JOIN b as b_alias ON a_alias.b_fk = b_alias.id WHERE a_alias.unit_name LIKE ''some_value'' AND a.id = a_alias.id;

Puede usar a_alias en la sección SET a la derecha del signo igual si es necesario. Los campos a la izquierda del signo igual no requieren una referencia de tabla, ya que se considera que son de la tabla "a" original.