105

条件付きINSERTを作成するのに苦労しています

インスタンスIDが一意である列(インスタンス、ユーザー、アイテム)を持つx_tableがあります。ユーザーが特定のアイテムをまだ持っていない場合にのみ、新しい行を挿入したいと思います。

たとえば、instance = 919191 user = 123 item=456を挿入しようとしています

Insert into x_table (instance, user, item) values (919191, 123, 456) 
    ONLY IF there are no rows where user=123 and item=456 

正しい方向への助けや指導をいただければ幸いです。

4

13 に答える 13

127

挿入を実行するときに選択するテーブルにDBMSが制限を課していない場合は、次のことを試してください。

INSERT INTO x_table(instance, user, item) 
    SELECT 919191, 123, 456
        FROM dual
        WHERE NOT EXISTS (SELECT * FROM x_table
                             WHERE user = 123 
                               AND item = 456)

これにdualは、1行のみのテーブルがあります(元々はOracleにあり、現在はmysqlにもあります)。ロジックは、SELECTステートメントが必要な値を含む単一行のデータを生成することですが、値がまだ見つからない場合に限ります。

または、MERGEステートメントを確認してください。

于 2009-05-27T04:31:08.277 に答える
54

INSERT IGNORE(user、item)に一意のインデックスがある場合、行を更新または挿入する代わりに、whichを使用して挿入をサイレントに無視することもできます。

クエリは次のようになります。

INSERT IGNORE INTO x_table(instance, user, item) VALUES (919191, 123, 456)

で一意のインデックスを追加できますCREATE UNIQUE INDEX user_item ON x_table (user, item)

于 2012-04-25T06:52:03.827 に答える
37

あなたはそのようなことを試みたことがありますか?

INSERT INTO x_table (instance, user, item)
SELECT 919191 as instance, 123 as user, 456 as item
FROM x_table
WHERE (user=123 and item=456)
HAVING COUNT(*) = 0;
于 2011-10-15T21:35:16.897 に答える
10

を使用して、次のUNIQUE(user, item)ことを行います。

Insert into x_table (instance, user, item) values (919191, 123, 456) 
  ON DUPLICATE KEY UPDATE user=123

このビットは、重複がある場合に実際には何もせずに句user=123の構文に一致する「no-op」です。ON DUPLICATE

于 2009-05-27T04:37:40.513 に答える
3

一意の制約を設定したくない場合、これは魅力のように機能します。

INSERT INTO `table` (`column1`, `column2`) SELECT 'value1', 'value2' FROM `table` WHERE `column1` = 'value1' AND `column2` = 'value2' HAVING COUNT(`column1`) = 0

それが役に立てば幸い !

于 2014-08-29T11:23:48.333 に答える
3

あなたが欲しいのはですINSERT INTO table (...) SELECT ... WHERE ...MySQL5.6マニュアルから。

あなたの場合それは:

INSERT INTO x_table (instance, user, item) SELECT 919191, 123, 456 
WHERE (SELECT COUNT(*) FROM x_table WHERE user=123 AND item=456) = 0

または、実行するかどうかを決定するために複雑なロジックを使用していないため、これら2つの列の組み合わせにキーをINSERT設定してからを使用することもできます。UNIQUEINSERT IGNORE

于 2015-03-27T18:49:13.327 に答える
1

(x_table.user、x_table.item)が一意であるという制約を追加すると、同じユーザーとアイテムで別の行を挿入すると失敗します。

例えば:

mysql> create table x_table ( instance integer primary key auto_increment, user integer, item integer, unique (user, item));
Query OK, 0 rows affected (0.00 sec)

mysql> insert into x_table (user, item) values (1,2),(3,4);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> insert into x_table (user, item) values (1,6);
Query OK, 1 row affected (0.00 sec)

mysql> insert into x_table (user, item) values (1,2);
ERROR 1062 (23000): Duplicate entry '1-2' for key 2
于 2009-05-27T04:00:26.117 に答える
1

データを挿入する前に重複をチェックすることは良いことですが、重複データが誤って挿入されないように、列に一意の制約/インデックスを設定することをお勧めします。

于 2009-05-27T04:03:02.893 に答える
1

次の解決策を使用して、問題を解決できます。

INSERT INTO x_table(instance, user, item) 
    SELECT 919191, 123, 456
        FROM dual
        WHERE 123 NOT IN (SELECT user FROM x_table)
于 2018-08-15T22:55:36.077 に答える
0

Alexの応答を少し変更し、既存の列の値を参照することもできます。

Insert into x_table (instance, user, item) values (919191, 123, 456) 
  ON DUPLICATE KEY UPDATE user=user
于 2011-07-25T05:50:04.630 に答える
0

つまり、これはPostgreSQLの略です

INSERT INTO x_table
SELECT NewRow.*
FROM (SELECT 919191 as instance, 123 as user, 456 as item) AS NewRow
LEFT JOIN x_table
ON x_table.user = NewRow.user AND x_table.item = NewRow.item
WHERE x_table.instance IS NULL
于 2013-03-13T13:01:09.057 に答える
0

私は今日、SELECTステートメントに句がなく、テーブルをまったく読み取らWHEREない場合でも、ステートメントに条件が含まれる可能性があることを発見しました。FROM

これにより、次の構成を使用して条件付きで何かを挿入することが非常に簡単になります。

SELECT ... INTO @condition;
-- or if you prefer: SET @condition = ...

INSERT INTO myTable (col1, col2) SELECT 'Value 1', 'Value 2' WHERE @condition;

MySQL5.7およびMariaDB10.3でこれをテストしました。

于 2020-09-28T07:55:06.990 に答える
-1
Insert into x_table (instance, user, item) values (919191, 123, 456) 
    where ((select count(*) from x_table where user=123 and item=456) = 0);

構文はDBによって異なる場合があります...

于 2009-05-27T03:56:41.883 に答える