INSERISCI IN ... SELEZIONA DA ... ALL'AGGIORNAMENTO DELLA CHIAVE DUPLICATA


116

Sto eseguendo una query di inserimento in cui la maggior parte di molte colonne dovrebbe essere aggiornata ai nuovi valori se esistesse già una chiave univoca. Funziona in questo modo:

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

Non sono sicuro di quale UPDATEdovrebbe essere la sintassi per la clausola. Come faccio a fare riferimento alla riga corrente dalla SELECTclausola?

Risposte:


172

MySQL presume che la parte prima dell'equals faccia riferimento alle colonne denominate nella clausola INSERT INTO e la seconda parte faccia riferimento alle colonne 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, ...

6
@dnagirl: SUGGERIMENTO: non provare ad aggiornare nessuna delle colonne PK, solo quelle che devono essere aggiornate vanno nella lista
lexu

45
La sintassi suggerita funziona ed t.è richiesta. Ho anche trovato un articolo su xaprb ( xaprb.com/blog/2006/02/21/flexible-insert-and-update-in-mysql ) che utilizza questa sintassi: on duplicate key update b = values(b), c = values(c). Funziona anche questo.
dnagirl

9
Nota: questo non funzionerà quando l'istruzione SELECT ha una clausola GROUP BY
joHN

11
@john Cosa fare se l'istruzione SELECT ha una clausola GROUP BY
Kathir

2
dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html dice `in MySQL 5.6.4 e versioni successive, INSERT ... SELECT ON DUPLICATE KEY UPDATE le istruzioni sono contrassegnate come non sicure per la replica basata su istruzioni ... Inoltre, a partire da MySQL 5.6.6, un'istruzione INSERT ... ON DUPLICATE KEY UPDATE su una tabella con più di una chiave univoca o primaria viene anch'essa contrassegnata come non sicura.
Abdul Muneer

51

Anche se sono molto in ritardo su questo, ma dopo aver visto alcune domande legittime per coloro che volevano usare INSERT-SELECTquery with GROUP BYclause, ho escogitato il lavoro per questo.

Prendendo ulteriormente la risposta di Marcus Adams e la contabilità GROUP BYin essa, è così che risolverei il problema usandoSubqueries 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, ...

8
Questa è la risposta giusta per domande con COUNT, GROUP ecc. Grazie.
Kostanos

Grazie mille, amico! Mi è piaciuto molto questo approccio, specialmente perché mi permette di creare un meccanismo come Continuous Query, qualcosa che fa InfluxDB.
Miere

1
Puoi anche utilizzare field = VALUES (field) nell'aggiornamento duplicato come nella risposta in stackoverflow.com/questions/16935896/…
Erik Melkersson
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.