SISIPKAN KE… PILIH DARI… PADA UPDATE KUNCI DUPLIKAT

116

Saya melakukan kueri penyisipan di mana sebagian besar dari banyak kolom perlu diperbarui ke nilai baru jika kunci unik sudah ada. Ini berjalan seperti ini:

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

Saya tidak yakin seperti apa sintaks untuk UPDATEklausa tersebut. Bagaimana cara saya merujuk ke baris saat ini dari SELECTklausa?

dnagirl.dll
sumber

Jawaban:

172

MySQL akan mengambil bagian sebelum referensi sama dengan kolom yang dinamai dalam klausa INSERT INTO, dan bagian kedua merujuk ke kolom 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, ...
Marcus Adams
sumber
6
@dnagirl: TIP: jangan mencoba memperbarui kolom PK apa pun, hanya yang perlu diperbarui masuk ke daftar
lexu
45
Sintaks yang Anda sarankan berfungsi dan t.diperlukan. Saya juga menemukan sebuah artikel tentang xaprb ( xaprb.com/blog/2006/02/21/flexible-insert-and-update-in-mysql ) yang menggunakan sintaks ini: on duplicate key update b = values(b), c = values(c). Ini juga berhasil.
dnagirl
9
Catatan: Ini tidak akan bekerja ketika pernyataan SELECT memiliki klausa GROUP BY
joHN
11
@ John Apa yang harus dilakukan jika pernyataan SELECT memiliki klausa GROUP BY
Kathir
2
dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html mengatakan `` di MySQL 5.6.4 dan yang lebih baru, INSERT ... SELECT ON DUPLICATE KEY UPDATE Pernyataan ditandai sebagai tidak aman untuk replikasi berbasis pernyataan ... Selain itu, dimulai dengan MySQL 5.6.6, pernyataan INSERT ... ON DUPLICATE KEY UPDATE terhadap tabel yang memiliki lebih dari satu kunci unik atau primer juga ditandai sebagai tidak aman.`
Abdul Muneer
51

Meskipun saya sangat terlambat untuk ini tetapi setelah melihat beberapa pertanyaan yang sah bagi mereka yang ingin menggunakan INSERT-SELECTquery dengan GROUP BYklausa, saya menemukan solusi untuk ini.

Mengambil lebih jauh jawaban dari Marcus Adams dan akuntansi GROUP BYdi dalamnya, inilah cara saya memecahkan masalah dengan menggunakanSubqueries 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, ...
iCurious
sumber
8
Ini adalah jawaban yang tepat untuk pertanyaan dengan COUNT, GROUP dll .. Terima kasih.
Kostanos
Terima kasih banyak, bung! Saya sangat menyukai pendekatan ini, khususnya karena ini memungkinkan saya membuat mekanisme seperti Continuous Query, sesuatu yang dilakukan InfluxDB.
Miere
1
Anda juga bisa menggunakan field = VALUES (field) di pembaruan duplikat seperti dalam jawaban di stackoverflow.com/questions/16935896/…
Erik Melkersson