【问题标题】: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. 

【问题讨论】:

    标签: python mysql sql


    【解决方案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_acolumn_bcolumn_c 具有相同值的行,则数据库将拒绝插入,您将在 Python 中看到异常。

    【讨论】:

    • insert IGNONE 可能在这里可用(如果不需要向用户报告)
    • @fifonik:当然,如果这是可以接受的,但 OP 没有表明这一点。
    • 记住INSERT IGONE 在插入失败时,innoDB 表引擎会“浪费”auto_increment 值@fifonik
    • 另外,INSERT IGNOREall 错误变为警告,而不仅仅是重复键错误。这可能很棘手。 ON DUPLICATE KEY UPDATE 是要走的路。
    猜你喜欢
    • 2011-03-11
    • 1970-01-01
    • 1970-01-01
    • 2014-02-15
    • 2014-04-04
    • 1970-01-01
    • 2014-03-08
    相关资源
    最近更新 更多