如果某些值不存在,MySQL INSERT 多行

标签 mysql sql

我有以下查询可以正常工作:

INSERT INTO Events (user_ID, event_type, event_creation_datetime, unit_ID)
SELECT 10, 'user_other_unit_moved', now(), 8383
FROM Events
WHERE NOT EXISTS (SELECT event_ID FROM Events WHERE event_type = 'user_other_unit_moved' AND unit_ID = 8383)
LIMIT 1;

查询的作用是检查我的事件表中是否存在与我希望插入的事件类型和单元 ID 相匹配的行。如果找到现有记录,则不会继续执行 INSERT。但是,如果它没有找到记录,则会继续执行 INSERT。

这是我的事件表的结构:

CREATE TABLE `Events` (
  `event_ID` int(11) NOT NULL,
  `user_ID` int(11) NOT NULL,
  `event_type` varchar(35) NOT NULL,
  `event_creation_datetime` datetime NOT NULL,
  `unit_ID` int(10) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `Events`
  ADD PRIMARY KEY (`event_ID`),
  ADD KEY `unit_ID` (`unit_ID`);

ALTER TABLE `Events`
  MODIFY `event_ID` int(11) NOT NULL AUTO_INCREMENT;
COMMIT;

我遇到的问题是在尝试插入多行时试图使上述查询正常工作。我知道如何使用逗号分隔的 VALUES 插入多行,但无论我尝试什么,我都会遇到语法错误。这是我一直在玩的查询:

INSERT INTO Events (user_ID, event_type, event_creation_datetime, unit_ID)
VALUES (
(SELECT 10, 'user_other_unit_moved', now(), 8383
FROM Events
WHERE NOT EXISTS (SELECT event_ID FROM Events WHERE event_type = 'user_other_unit_moved' AND unit_ID = 8383)
 LIMIT 1)),
(SELECT 10, 'user_other_unit_moved', now(), 8380
FROM Events
WHERE NOT EXISTS (SELECT event_ID FROM Events WHERE event_type = 'user_other_unit_moved' AND unit_ID = 8380)
 LIMIT 1))
);

但是,无论我尝试什么(插入、删除括号等),我都会得到通用的“您的 SQL 语法有错误;”或“操作数应仅包含 1 列”。

我还根据其他 StackOverflow 帖子尝试了这个替代方案:

INSERT IGNORE INTO Events (event_ID, user_ID, event_type, event_creation_datetime, unit_ID)
VALUES
(SELECT (SELECT event_ID FROM Events WHERE event_type = 'user_other_unit_moved' AND unit_ID = 8383), 10, 'user_other_unit_moved', now(), 8383),
(SELECT (SELECT event_ID FROM Events WHERE event_type = 'user_other_unit_moved' AND unit_ID = 8383), 10, 'user_other_unit_moved', now(), 8383);

但是即使我尝试使用临时表返回结果,也会失败并显示“无法在 FROM 子句中指定更新目标表”。

这只是我的语法错误,还是我试图做一些我的查询布局方式不可能做的事情?如果这只是一个错误,我将如何编写查询以使其按我的预期工作?请注意,我不想使用多查询 - 我希望查询作为一个语句工作。

谢谢, 阿杰

最佳答案

不要使用 VALUES,只需使用 INSERT ... SELECT 并且不要 FROM events
然后 UNION ALL

此代码适用于 MySql 5.6:

INSERT INTO Events (user_ID, event_type, event_creation_datetime, unit_ID)
SELECT * 
FROM (
  SELECT 10 user_ID, 'user_other_unit_moved' event_type, 
    now() event_creation_datetime, 8383 unit_ID
  UNION ALL
  SELECT 10, 'user_other_unit_moved', now(), 8380
) t
WHERE NOT EXISTS (
  SELECT 1 FROM Events e 
  WHERE e.event_type = t.event_type AND e.unit_ID = t.unit_ID
);

参见 demo .

此代码适用于 MySql 5.7+:

INSERT INTO Events (user_ID, event_type, event_creation_datetime, unit_ID)
SELECT * FROM (
  SELECT 10, 'user_other_unit_moved', now(), 8383
  WHERE NOT EXISTS (SELECT 1 FROM Events WHERE event_type = 'user_other_unit_moved' AND unit_ID = 8383)
  UNION ALL
  SELECT 10, 'user_other_unit_moved', now(), 8380
  WHERE NOT EXISTS (SELECT 1 FROM Events WHERE event_type = 'user_other_unit_moved' AND unit_ID = 8380)
) t 

参见 demo

这对于 MySql 8.0+:

INSERT INTO Events (user_ID, event_type, event_creation_datetime, unit_ID)
SELECT 10, 'user_other_unit_moved', now(), 8383
WHERE NOT EXISTS (SELECT 1 FROM Events WHERE event_type = 'user_other_unit_moved' AND unit_ID = 8383)
UNION ALL
SELECT 10, 'user_other_unit_moved', now(), 8380
WHERE NOT EXISTS (SELECT 1 FROM Events WHERE event_type = 'user_other_unit_moved' AND unit_ID = 8380);

参见 demo .

关于如果某些值不存在,MySQL INSERT 多行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57251327/

相关文章:

php - MySQLi 返回一个带有 bind_result 的数组并且获取不工作

java - 初始 SessionFactory 创建失败 : java. lang.NoClassDefFoundError: javax/persistence/NamedStoredProcedureQuery

php - 使用 PHP 连接到数据库时出错

使用带有聚合函数的 WHERE 语句的 SQL

php - 如果它具有相同的值,如何检查一行中的列?

php - MySQL/PHP 更新查询未执行

mysql - 限制左连接?

mysql - 如何在 MySql 中进行口音敏感搜索

PHP/MySQL 从 3 个不同的表中选择数据并将结果显示在一张表中

sql - 用于逆透视的存储过程