表題の通りで「なければ挿入」「あれば無視(更新でもOK)」というSQLを一回のクエリで
かつすべての条件で汎用的に行いたいです
よく使われるような文なのに簡潔に書けるものがないのが不思議です
今回はmysql 5.6.40 を使いました。
テーブルは以下のような形です
このテーブルに、「str1がa」かつ「str2がa」のものが「なければ挿入」「あれば無視(更新でもOK)」をしたいです
CREATE TABLE IF NOT EXISTS `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `str1` text NOT NULL, `str2` text NOT NULL, PRIMARY KEY (`id`) )
まず、この内容でググるとすぐに出てくるのが
「ON DUPLICATE KEY UPDATE」
これに関しては、主キー、ユニークキーが検索対象の条件でない場合は動かないので
除外してください、今回はインデックスなしの「str1」「str2」を対象とします
「IGNORE」も同じ理由で除外だと思われます。
また、「str1とstr2」を合体させたユニークカラムを作る、は期待する情報ではありませんテーブルの構造はこの形のままでSQLが知りたいです。
次に考えられるのが副問い合わせというもの
下記で動くのであれば、非常に直感的で分かりやすいのですが
これでは文法エラーになります。。。SQLの設計者はなぜこれで動くようにしなかったのか理解に苦しみます
INSERT INTO `test`(str1,str2) VALUES('a','a') WHERE NOT EXISTS (SELECT * FROM `test` WHERE `str1` = 'a' AND `str2` = 'a');
そこで次のようにすると一部条件で動くようになるのですが
今回の場合は動きません、「a」が重複しているので「#1060 - Duplicate column name 'a'」となります
INSERT INTO `test`(str1,str2) SELECT * FROM (SELECT 'a','a') AS TMP WHERE NOT EXISTS (SELECT * FROM `test` WHERE `str1` = 'a' AND `str2` = 'a');
aとbにすればエラーは起きず期待する結果になります
INSERT INTO `test`(str1,str2) SELECT * FROM (SELECT 'a','b') AS TMP WHERE NOT EXISTS (SELECT * FROM `test` WHERE `str1` = 'a' AND `str2` = 'b');
「なければ挿入」「あれば無視(更新でもOK)」というSQLを一回のクエリで、かつすべての条件で汎用的に行うのは不可能なのでしょうか
ベテランの方ご教授いただけますと幸いです
maisumakun様からの回答で解決しました
同じ内容で悩んでいる方のために、SQLの具体例を書いておきます
お役立てください
INSERT INTO `test`(str1,str2) SELECT * FROM (SELECT 'a'as col1,'a'as col2) AS TMP WHERE NOT EXISTS (SELECT * FROM `test` WHERE `str1` = 'a' AND `str2` = 'a');
回答2件
あなたの回答
tips
プレビュー