MySQL条件插入

我有一个困难的时间形成条件插入

我有x_table与实例ID唯一的列(实例,用户,项目)。 我只想在用户已经没有给定项目的情况下插入一个新行。

例如试图插入实例= 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 

任何帮助或正确的方向指导将不胜感激。

如果您的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是只有一行的表格(最初在Oracle中找到,现在在其他地方也是如此)。 逻辑是,SELECT语句生成具有所需值的单行数据,但只有当这些值尚未找到时才会生成。

或者,查看MERGE语句。

您还可以使用INSERT IGNORE ,它在(user,item)上有一个唯一索引时静默地忽略插入,而不是更新或插入一行。

查询将如下所示:

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

您可以使用CREATE UNIQUE INDEX user_item ON x_table (user, item)添加唯一索引。

你有没有尝试过这样的事情?

 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; 

使用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子句的语法相匹配,而没有重复的时候实际做任何事情。

如果你不想设置一个独特的约束,这就像一个魅力:

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

希望它有帮助!

如果添加(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 

虽然在插入数据之前检查重复是一件好事,但我建议你在列上放一个唯一的约束/索引,以免错误地插入重复的数据。

你想要的是INSERT INTO table (...) SELECT ... WHERE ... 从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或不,你可以设置一个UNIQUE键在这两列的组合,然后使用INSERT IGNORE

 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 …

对Alex的回应稍作修改,你也可以引用现有的列值:

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

所以这个代表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