如果行中不存在所有值,则插入记录[重复]
Posted
技术标签:
【中文标题】如果行中不存在所有值,则插入记录[重复]【英文标题】:Insert record if all values do not exist in a row [duplicate] 【发布时间】:2019-07-06 15:42:26 【问题描述】:我有三列:a、b、c。
如果 a、b、c 不存在于一行中,我想插入一个新行。
使用 Python 来做到这一点。
INSERT INTO mytable(column_a, column_b, column_c)
VALUES(value_a, value_b, value_c)
WHERE value_a, value_b, value_c are all unique in existing rows.
【问题讨论】:
【参考方案1】:如果您可以实现一种通用机制来避免列 column_a/b/c 上的重复,您可以简单地在两个列上添加一个复合唯一约束,例如
ALTER TABLE mytable
ADD CONSTRAINT constr_ID UNIQUE (column_a, column_b, column_c);
如果在表上发生任何会产生重复的操作,mysql 将引发约束冲突错误。您可以使用 ON DUPLICATE KEY UPDATE
选项忽略错误:
INSERT INTO mytable(column_a, column_b, column_c)
VALUES(value_a, value_b, value_c)
ON DUPLICATE KEY UPDATE column_a = column_a;
在这个 demo on DB Fiddle 中,我们插入了 3 条记录,其中 2 条重复,我们最终在表中得到了 2 条记录,正如预期的那样。
另一方面,如果您想将重复检查限制为仅一个查询,和/或如果您想避免在重复键上浪费自动增量序列,那么您可以使用 INSERT ... SELECT
语句,其中包含WHERE NOT EXISTS
进行重复检查的条件:
INSERT INTO mytable(column_a, column_b, column_c)
SELECT src.*
FROM (SELECT value_a column_a, value_b column_b, value_c column_c) src
WHERE NOT EXISTS (
SELECT 1
FROM mytable
WHERE
column_a = src.column_a
AND column_b = src.column_b
AND column_c = src.column_c
);
如果您尝试插入重复项,查询将不执行任何操作(并且不会生成错误或警告)。
Demo on DB Fiddle.
【讨论】:
我尝试了第一个实现,但没有任何内容插入到我的表中。 @brainygrunt :如果您尝试插入重复项,则不会插入任何内容。否则,记录将被插入。 同意。但是根本没有插入任何内容。由于该表当前为空,因此应至少插入一行。 @brainygrunt :请参阅 this DB Fiddle demo,它演示了该功能的工作原理。 谢谢!这行得通。但是,我的 id 自动增量跳过了 1、2、6、40、121 等数字。【参考方案2】:解决此问题的一种方法是在三列上创建唯一索引。如果您尝试插入重复的行,数据库将拒绝插入。无需特殊查询。这应该适用于任何关系数据库,而不仅仅是 MySQL。
用这个创建唯一索引:
CREATE UNIQUE INDEX a_b_c ON mytable (column_a, column_b, column_c)
像这样插入:
INSERT INTO mytable(column_a, column_b, column_c) VALUES (value_a, value_b, value_c)
如果已经存在与列 column_a
、column_b
和 column_c
具有相同值的行,则数据库将拒绝插入,您将在 Python 中看到异常。
【讨论】:
insert IGNONE
可能在这里可用(如果不需要向用户报告)
@fifonik:当然,如果这是可以接受的,但 OP 没有表明这一点。
记住INSERT IGONE
在插入失败时,innoDB 表引擎会“浪费”auto_increment 值@fifonik
另外,INSERT IGNORE
将 all 错误变为警告,而不仅仅是重复键错误。这可能很棘手。 ON DUPLICATE KEY UPDATE
是要走的路。以上是关于如果行中不存在所有值,则插入记录[重复]的主要内容,如果未能解决你的问题,请参考以下文章