我很难形成条件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
非常感谢任何正确方向的帮助或指导。
答案 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上进行了测试。