MySQL条件插入

时间:2009-05-27 03:48:01

标签: mysql insert conditional

我很难形成条件INSERT

我有x_table的列(实例,用户,项目),其中实例ID是唯一的。我想仅在用户已经没有给定项目时才插入新行。

例如,尝试插入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 

非常感谢任何正确方向的帮助或指导。

13 个答案:

答案 0 :(得分:104)

如果您的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中找到,现在也在mysql中)。逻辑是SELECT语句生成具有所需值的单行数据,但仅在尚未找到值时才生成。

或者,查看MERGE语句。

答案 1 :(得分:44)

您还可以使用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)添加唯一索引。

答案 2 :(得分:25)

你有没有试过这样的东西?

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;

答案 3 :(得分:10)

使用UNIQUE(user, item),执行:

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

user=123位是一个“无操作”,以匹配ON DUPLICATE子句的语法,而在没有重复的情况下实际执行任何操作。

答案 4 :(得分:2)

如果您不想设置唯一约束,这就像魅力一样:

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

希望它有所帮助!

答案 5 :(得分: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

答案 6 :(得分:1)

虽然在插入数据之前检查重复是好的,但我建议你在列上放置一个唯一的约束/索引,这样就不会错误地插入重复的数据。

答案 7 :(得分:1)

你想要的是INSERT INTO table (...) SELECT ... WHERE ...。来自MySQL 5.6 manual

在你的情况下是:

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键,然后使用{{ 1}}。

答案 8 :(得分:0)

Insert into x_table (instance, user, item) values (919191, 123, 456) 
    where ((select count(*) from x_table where user=123 and item=456) = 0);

语法可能因您的数据库而异......

答案 9 :(得分:0)

对Alex的响应稍作修改,您也可以只引用现有的列值:

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

答案 10 :(得分: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

答案 11 :(得分:0)

您可以使用以下解决方案来解决您的问题:

INSERT INTO x_table(instance, user, item) 
    SELECT 919191, 123, 456
        FROM dual
        WHERE 123 NOT IN (SELECT user FROM x_table)

答案 12 :(得分: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;

在MySQL 5.7和MariaDB 10.3上进行了测试。