…に挿入…重複するキーの更新時に…から選択


116

一意のキーが既に存在する場合、多くの列のほとんどを新しい値に更新する必要がある挿入クエリを実行しています。それはこのようなものになります:

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

UPDATE句の構文がどうあるべきかわかりません。SELECT句から現在の行を参照するにはどうすればよいですか?

回答:


172

MySQLは、equalsの前の部分がINSERT INTO句で指定された列を参照し、2番目の部分が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:ヒント: PK列の更新を試みないでください。更新が必要な列のみがリストに含まれます
lexu

45
提案された構文は機能し、これt.は必須です。また、この構文を使用するxaprbに関する記事(xaprb.com/blog/2006/02/21/flexible-insert-and-update-in-mysql)も見つけましたon duplicate key update b = values(b), c = values(c)。これも機能します。
dnagirl

9
注:これは、SELECTステートメントにGROUP BY句がある場合は機能しません
joHN

11
@john SELECTステートメントにGROUP BY句がある場合の対処法
Kathir

2
dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.htmlは「MySQL 5.6.4以降ではINSERT ... SELECT ON DUPLICATE KEY UPDATEステートメントはステートメントベースのレプリケーションに対して安全ではないとしてフラグが立てられる... MySQLの5.6.6、複数の一意キーまたは主キーにもunsafe.`としてマークされたテーブルに対してINSERT ... ON DUPLICATE KEY UPDATE文で始まる、また
アブドゥルMuneer

51

私はこれに非常に遅れていますが、INSERT-SELECTクエリwith GROUP BY句を使用したい人のためのいくつかの正当な質問を見て、私はこれの回避策を思いつきました。

マーカス・アダムスの答えをさらに取り入れて説明GROUP BYすると、これは私が使用して問題を解決する方法です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, ...

8
これは、COUNT、GROUPなどのクエリに対する正しい答えです。ありがとうございます。
コスタノス2015年

どうもありがとうございました!特にInfluxDBのように、Continuous Queryのようなメカニズムを作成できるため、このアプローチは本当に気に入りました。
Miere

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.