2016-09-03 19 views
0

特定の条件が満たされた場合、INSERTおよびON DUPLICATE KEYはどのように行全体を更新できますか? VALUES(date_added)の方が古い場合はrowを更新したいのですが、テーブルからはdate_addedの方が古いです。INSERT ...重複キー更新行IF date_added> VALUES(date_added)

私はこの記事を見てきました

https://thewebfellas.com/blog/conditional-duplicate-key-updates-with-mysql

INSERT INTO daily_events 
    (created_on, last_event_id, last_event_created_at) 
VALUES 
    ('2010-01-19', 23, '2010-01-19 10:23:11') 
ON DUPLICATE KEY UPDATE 
    last_event_id = IF(last_event_created_at < VALUES(last_event_created_at), VALUES(last_event_id), last_event_id), 
    last_event_created_at = IF(last_event_created_at < VALUES(last_event_created_at), VALUES(last_event_created_at), last_event_created_at); 

しかし、これは文を書くための柔軟な方法ではありません。

その後編集:

まず、条件は、あなたが条件列を更新行を配置するために注意を払わなければならないための最後の位置に、第二の更新、およびされる各フィールドのために評価されているため、その声明そうしないと、UPDATEにエラーが発生します。より正確に、私も有効であると、私は2つのUPDATE行を反転してきたこの文を、したいと思うすることが

INSERT INTO daily_events(created_on, last_event_id, last_event_created_at) VALUES('2010-01-19', 23, '2010-01-19 10:23:11') ON DUPLICATE KEY UPDATE last_event_created_at = GREATEST(last_event_created_at, VALUES(last_event_created_at)), last_event_id = (CASE WHEN last_event_created_at < VALUES(last_event_created_at) THEN VALUES(last_event_id) ELSE last_event_id END);

これは可能ではない理由は次のとおりです。

このアプローチを使用する際に重要なことは、フィールドを更新する順序が非常に重要であることです。私は間違って、クエリ全体がMySQLによって解釈された後に、1回のマス課題で更新が行われたという印象を受けました。しかし、彼らはそうではありません:割り当ては、クエリに表示される順序で発生します。

最近のイベントでupdateを実行すると、last_event_created_atフィールドは更新されますが、last_event_idフィールドは更新されません。これは、last_event_created_atVALUES(last_event_created_at)に等しくなるように、IFの2番目の値がlast_event_created_atと既に更新されているためです。クレイジーハァッ!

+0

私はあなたの質問で混乱しています。あなたの質問はあなたがしたいことをしているようです。 –

+0

私は列の順序を制御することができないので、条件を2回評価したくありません。そして、その例から、更新される最後の列が条件を持つ列であることがわかります。さもなければ、あなたは誤った値でテーブルを毒するでしょう。 – Nick

+0

誰が "-1"を与えましたか?説明無しにダウンボトムするのは無駄です。あなたは、私が将来あなたが考えるミスをやめさせているわけではありません。 – Nick

答えて

1

あなたのクエリはあなたが望むように思われるので、私は完全にその質問を理解していません。あなたはGREATEST()を使用して、それを簡素化することがあります

INSERT INTO daily_events(created_on, last_event_id, last_event_created_at) 
    VALUES('2010-01-19', 23, '2010-01-19 10:23:11') 
ON DUPLICATE KEY UPDATE 
    last_event_id = (CASE WHEN last_event_created_at < VALUES(last_event_created_at) THEN VALUES(last_event_id) ELSE last_event_id END), 
    last_event_created_at = GREATEST(last_event_created_at, VALUES(last_event_created_at)); 

(。CASEの使用は、同等の機能のためのANSI規格の好みです)

MySQLはときに、これらのすべてを更新」と言うする方法を提供していません。この条件は満たされます。

+0

私は最後に条件を持つ列を保持するという要件を取り除きたい(この場合は 'date_added'列)。この文をPerlで使用し、特定の列を検出して文の最後の行に置くコードを書くと、Perlコードが醜い、長く、非効率的に見えるようになります。 – Nick

+0

より正確には、 'INSERT INTO daily_events(created_on、last_event_id、last_event_created_at) VALUES( '2010-01-19'、23、 '2010-01-30)この2つの' UPDATE'行を反転させたこのステートメントは、 19十時23分11' 秒)DUPLICATE KEY UPDATE ON last_event_created_at = GREATEST(last_event_created_at、VALUES(last_event_created_at))、 last_event_id =(CASE WHEN last_event_created_at Nick

関連する問題