web-dev-qa-db-ja.com

MySQL条件付き挿入

条件付き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 

正しい方向への助けやガイダンスをいただければ幸いです。

90
The Unknown

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ステートメントをご覧ください。

107

(ユーザー、アイテム)に一意のインデックスがある場合、行を更新または挿入する代わりに、挿入をサイレントに無視する_INSERT IGNORE_を使用することもできます。

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

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

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

46
MrD

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

INSERT INTO x_table
SELECT 919191 as instance, 123 as user, 456 as item
FROM x_table
WHERE (user=123 and item=456)
HAVING COUNT(*) = 0;
26
temple

UNIQUE(user, item)を使用して、次を実行します。

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

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

10
Alex Martelli

ユニーク制約を設定したくない場合、これは魅力のように機能します:

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

それが役に立てば幸い !

2
Gew

必要なのはINSERT INTO table (...) SELECT ... WHERE ...です。 from MySQL 5.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

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

1
martin

(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
1
NickZoic

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

1
Beatles1692

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

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

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

INSERT INTO x_table(instance, user, item) 
    SELECT 919191, 123, 456
        FROM dual
        WHERE 123 NOT IN (SELECT user FROM x_table)
0
Keith Becker
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によって異なる場合があります...

0
Rick J

これは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
0
xsubira