2010-03-18 17 views
95

Estoy haciendo una consulta de inserción donde la mayoría de las columnas necesitarían actualizarse a los nuevos valores si ya existía una clave única. Es algo parecido a esto:INSERT INTO ... SELECT FROM ... ON DUPLICATE KEY UPDATE

INSERT INTO lee(exp_id, created_by, 
       location, animal, 
       starttime, endtime, entct, 
       inact, inadur, inadist, 
       smlct, smldur, smldist, 
       larct, lardur, lardist, 
       emptyct, emptydur) 
SELECT id, uid, t.location, t.animal, t.starttime, t.endtime, t.entct, 
     t.inact, t.inadur, t.inadist, 
     t.smlct, t.smldur, t.smldist, 
     t.larct, t.lardur, t.lardist, 
     t.emptyct, t.emptydur 
FROM tmp t WHERE uid=x 
ON DUPLICATE KEY UPDATE ...; 
//update all fields to values from SELECT, 
//  except for exp_id, created_by, location, animal, 
//  starttime, endtime 

No estoy seguro de lo que debería ser la sintaxis de la cláusula UPDATE. ¿Cómo me refiero a la fila actual de la cláusula SELECT?

Respuesta

125

MySQL asumirá que la parte anterior a la igualdad hace referencia a las columnas nombradas en la cláusula INSERT INTO, y la segunda parte hace referencia a las columnas SELECT.

INSERT INTO lee(exp_id, created_by, location, animal, starttime, endtime, entct, 
       inact, inadur, inadist, 
       smlct, smldur, smldist, 
       larct, lardur, lardist, 
       emptyct, emptydur) 
SELECT id, uid, t.location, t.animal, t.starttime, t.endtime, t.entct, 
     t.inact, t.inadur, t.inadist, 
     t.smlct, t.smldur, t.smldist, 
     t.larct, t.lardur, t.lardist, 
     t.emptyct, t.emptydur 
FROM tmp t WHERE uid=x 
ON DUPLICATE KEY UPDATE entct=t.entct, inact=t.inact, ... 
+5

@dnagirl: ** TIP: ** no trate de actualice cualquiera de las columnas PK, solo aquellas que necesitan actualización van a la lista – lexu

+37

Su sintaxis sugerida funciona y se requiere 't'. También encontré un artículo sobre xaprb (http://www.xaprb.com/blog/2006/02/21/flexible-insert-and-update-in-mysql/) que usa esta sintaxis: 'en la actualización de clave duplicada b = valores (b), c = valores (c) '. Esto también funciona – dnagirl

+7

Nota: Esto no funcionará cuando la instrucción SELECT tenga una cláusula GROUP BY – joHN

28

Aunque soy muy tarde para esto, pero después de ver algunas preguntas legítimas para aquellos que querían utilizar INSERT-SELECT consulta con GROUP BY cláusula, se me ocurrió con el trabajo en torno a esto.

Tomando aún más la respuesta de Marcus Adams y contabilidad GROUP BY en ella, esto es cómo iba a resolver el problema mediante el uso de Subqueries in the FROM Clause

INSERT INTO lee(exp_id, created_by, location, animal, starttime, endtime, entct, 
       inact, inadur, inadist, 
       smlct, smldur, smldist, 
       larct, lardur, lardist, 
       emptyct, emptydur) 
SELECT sb.id, uid, sb.location, sb.animal, sb.starttime, sb.endtime, sb.entct, 
     sb.inact, sb.inadur, sb.inadist, 
     sb.smlct, sb.smldur, sb.smldist, 
     sb.larct, sb.lardur, sb.lardist, 
     sb.emptyct, sb.emptydur 
FROM 
(SELECT id, uid, location, animal, starttime, endtime, entct, 
     inact, inadur, inadist, 
     smlct, smldur, smldist, 
     larct, lardur, lardist, 
     emptyct, emptydur 
FROM tmp WHERE uid=x 
GROUP BY location) as sb 
ON DUPLICATE KEY UPDATE entct=sb.entct, inact=sb.inact, ... 
+6

Esta es la respuesta correcta para consultas con COUNT, GROUP, etc. Gracias. – Kostanos

+0

¡Muchas gracias, amigo! Realmente me gustó este enfoque, especialmente porque me permite crear un mecanismo como Continuous Query, algo que InfluxDB hace. – Miere

+0

Me alegra oír eso – iConfused

Cuestiones relacionadas