【问题标题】:How to use MySql 'Insert Ignore into' query to insert records based on some values from a different table如何使用 MySql 'Insert Ignore into' 查询插入基于来自不同表的某些值的记录
【发布时间】:2015-10-02 18:45:24
【问题描述】:

我有两张如下表。下面提到的两个表中的 Id 列值都是自动递增的。

登录信息
+----+------------+-------------+
| Id |LoginName |IP |
+------+----------+-------------+
| 1 |User1 |aa.bb.cc.dd|
| 2 |User2 |xx.xx.xx.xx|
| 3 |User3 |ii.ii.ii.ii|
+----+------------+-------------+

用户组
+----+------------+-------------+
| Id |LoginName |Groups |
+------+----------+-------------+
| 1 |User1 |Group1 |
| 2 |User1 |Default |
| 3 |User2 |Group2 |
| 4 |User3 |Group3 |
+----+------------+-------------+

LoginInfo 表中的每个用户都应该是 UserGroups 表中“默认”组的成员。因此,在上表中,User1 与“默认”组相关联,但 User2 和 User3 没有。

我想检查是否为 UserGroups 表中的每个用户添加了“默认”组条目。如果可用,则忽略插入,否则为该用户插入一条新记录。

我试过的mysql查询是
INSERT IGNORE INTO USERGROUPS(LOGINNAME, GROUPS) SELECT LOGINNAME, 'Default' FROM LOGININFO L WHERE L.IP IS NOT NULL;
执行后,消息显示为 3 行受影响,UserGroups 表看起来像

+----+------------+-------------+
| Id |LoginName |Groups |
+------+----------+-------------+
| 1 |User1 |Group1 |
| 2 |User1 |Default |
| 3 |User2 |Group2 |
| 4 |User3 |Group3 |
| 5 |User1 |Default |
| 6 |User2 |Default |
| 7 | User3 | Default |
+----+------------+-------------+

但我真正寻找的是如下

+----+------------+-------------+
| Id |LoginName |Groups |
+------+----------+-------------+
| 1 |User1 |Group1 |
| 2 |User1 |Default |
| 3 |User2 |Group2 |
| 4 |User3 |Group3 |
| 5 |User2 |Default |
| 6 |User3 |Default |
+----+------------+-------------+

请告知有关查询的建议或任何解决方法。

【问题讨论】:

    标签: mysql


    【解决方案1】:

    您必须在执行 INSERT IGNORE 之前添加唯一约束:

    ALTER TABLE UserGroups ADD UNIQUE (LoginName, Groups)
    

    那么你可以执行这个查询:

    INSERT IGNORE INTO USERGROUPS(LOGINNAME, GROUPS)
    SELECT LOGINNAME, 'Default'
    FROM LOGININFO
    WHERE IP IS NOT NULL
    

    请看这个fiddle

    【讨论】:

    • 这是合乎逻辑的,现在我了解了 INSERT IGNORE 的用法。谢谢!!
    【解决方案2】:

    您可以形成INSERT 语句的SELECT 部分,以过滤掉重复记录:

    INSERT INTO UserGroups(LoginName, Groups) 
    SELECT LoginName, 'Default' 
    FROM LoginInfo AS l 
    WHERE l.IP IS NOT NULL 
          AND NOT EXISTS (SELECT 1
                          FROM UserGroups AS ug
                          WHERE ug.LoginName = l.LoginName AND ug.Groups = 'Default');
    

    那么您就不需要使用IGNORE

    Demo here

    【讨论】:

    • 成功了。谢谢 :) 所以在这种情况下,我们不需要更改表来添加唯一约束权。只是想知道使用INSERT IGNORE 比使用普通INSERT 有什么优势。
    • @Murali 我认为无论如何您都应该添加该唯一约束,以保证数据完整性。与使用INSERT IGNORE 的查询相比,我的查询可能更有效,因为它尝试插入更少的值。当您将它们与实际数据一起使用时,您可以告诉我们这两者的比较情况。
    • 是的,实际使用的表可能没有大量记录。目前我没有设置。一旦我得到设置,我将根据一些数字得到结果。
    最近更新 更多