2017-10-27 3 views
1

INSERTクエリを実行するときにON DUPLICATE KEY構文を使用することに慣れています。私はUPDATEクエリで同じことをしたいと思いますが、MySQLでは許可されていないようです。そうでなければ、構文を知らないだけです。UPDATEクエリを実行中にON DUPLICATE KEY機能が有効になっていますか?

私のテーブルには一意のインデックスがあり、UPDATEクエリでできるだけ多くのレコードを更新し、重複キーの原因となるレコードを無視または削除します。仮のクエリは次のようになります。

UPDATE votes SET user = 'foo' WHERE user = 'bar' 
    ON DUPLICATE KEY <ignore update or delete row>; 

私のデータベースに2人のユーザーをマージしようとしています。そのユーザーが既にトピックに対して既存の投票を行っている場合は、重複投票は無視できますが、この場合にはクエリ全体が失敗することはありません。理想的には、重複キーをトリガするレコードを削除したいのですが、それがクエリにロールインされていれば、ずっと優れています。

これは非常にまれなイベントです。この機能がUPDATEには存在しないのであれば、私は複数のクエリで必要なものを達成するための答えについています。

+0

「できるだけ多くのレコードを更新する」とはどういう意味ですか?クエリはレコードを1つだけ更新します。 – Barmar

+0

いいえ、特定のユーザーに対して1000の票があるかもしれません。これらの1000のうちの10個の更新が偽の鍵を引き起こす場合、私は990を成功させ、10を無視または削除します。 –

+0

私はおそらく私のVotesテーブルについての十分な情報を含んでいませんでした。ユニークキーはuser + topicにあります。ユーザーは、さまざまなトピックについて任意の数の投票権を持つことができますが、同じトピックについて複数の投票権を持つことはできません。ユーザーをマージする際に、ユーザーが以前に別々のユーザーが同じトピックに投票した場合があります。 –

答えて

1

あなたは自己結合してこれを確認することができます。これは、単一のクエリでUPDATEDELETEを結合することはできません

UPDATE votes AS v1 
LEFT JOIN votes AS v2 ON v1.topic = v2.topic AND v2.user = 'foo' 
SET v1.user = 'foo' 
WHERE v1.user = 'bar' 
AND v2.user IS NULL 

DEMO

。アトミック性を保証するトランザクションを使用して、別々に行う必要があります。 DELETEクエリは、トピックに基づいて複製されるレコードのみを削除する必要があります。

START TRANSACTION; 
DELETE v1 FROM votes AS v1 
JOIN votes AS v2 ON v1.topic = v2.topic 
WHERE v1.user = 'foo' AND v2.user = 'bar'; 
UPDATE votes SET user = 'foo' WHERE user = 'bar'; 
COMMIT; 
関連する問題