【问题标题】:mySQL INSERT IGNORE SELECT with UNIQUE KEY not workingmySQL INSERT IGNORE SELECT with UNIQUE KEY 不起作用
【发布时间】:2012-08-25 18:50:43
【问题描述】:

尝试通过使用 INSERT INTO SELECT 并连接两个源表来填充一个空的 MySQL 表。希望根据定义为 UNIQUE KEY 的两个目标表列IGNORE 插入重复行,但由于某种原因,仍在插入基于这两个列的重复行。

目标表定义:

CREATE TABLE `item` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `item_id` int(10) unsigned NOT NULL,
  `account_id` int(10) unsigned NOT NULL,
  `creation_date` datetime NOT NULL,
  `modification_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_item` (`item_id`,`account_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

插入查询:

INSERT IGNORE INTO item
            (id,
             item_id,
             account_id,
             creation_date,
             modification_date)
SELECT tblItem.ID,
       tblItem.itemID,
       tblOrder.accID,
       tblItem.itemTime,
       '0000-00-00 00:00:00'
FROM   tblItem
   INNER JOIN tblOrder
           ON tblItem.orderID = tblOrder.ID

重复的行被插入到 item 中,类似于以下内容:

id    item_id   account_id  creation_date           modification_date
2587    0       2           11/19/11 2:43           0000-00-00 00:00:00
2575    0       1120        11/17/11 19:32          0000-00-00 00:00:00
2575    0       1120        11/17/11 19:32          0000-00-00 00:00:00
382     60      193         0000-00-00 00:00:00     0000-00-00 00:00:00
941     95      916         10/28/11 15:52          0000-00-00 00:00:00
369     108     1           0000-00-00 00:00:00     0000-00-00 00:00:00
373     108     2           0000-00-00 00:00:00     0000-00-00 00:00:00
378     109     2           0000-00-00 00:00:00     0000-00-00 00:00:00
378     109     2           0000-00-00 00:00:00     0000-00-00 00:00:00

我错过了什么?

提前致谢!

【问题讨论】:

  • 您确定要加入tblOrdertblItem 而不是反过来吗?
  • 有区别吗?会这样编码: FROM tblItem INNER JOIN tblOrder ON tblOrder.ID = tblItem.orderID

标签: mysql insert


【解决方案1】:

SELECT 子句中尝试DISTINCT 关键字:

INSERT IGNORE INTO item
        (id,
         item_id,
         account_id,
         creation_date,
         modification_date)
SELECT DISTINCT tblItem.ID,
   tblItem.itemID,
   tblOrder.accID,
   tblItem.itemTime,
   '0000-00-00 00:00:00'
FROM   tblItem
   INNER JOIN tblOrder
       ON tblItem.orderID = tblOrder.ID

【讨论】:

    【解决方案2】:

    CREATE TABLE Syntax 中所述:

    UNIQUE 索引创建一个约束,使得索引中的所有值都必须是不同的。

    您在列 (item_id,account_id) 上定义了一个复合索引,因此该约束只要求每条记录都具有这两列的不同组合。

    在上面的示例中,似乎违反此约束的唯一记录是:

    +--------+---------+------------+------ --+----------------------+ |编号 | item_id | account_id |创建日期 |修改日期 | +--------+---------+------------+------ --+----------------------+ |第2575章0 | 1120 | 2011-11-17 19:32:00 | 0000-00-00 00:00:00 | |第2575章0 | 1120 | 2011-11-17 19:32:00 | 0000-00-00 00:00:00 | | 378 | 109 | 2 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 | | 378 | 109 | 2 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 | +--------+---------+------------+------ --+----------------------+

    但是,这些记录似乎也违反了 id 上的 PRIMARY KEY 约束(即它们似乎是相同的记录)。您显示的输出不太可能确实是您定义的 item 表的摘录:您几乎可以肯定正在查看其他表或查询的内容。

    一种可能的解释是您定义了一个同名的TEMPORARY TABLE,它隐藏了定义UNIQUE 约束的底层item 表。 SHOW CREATE TABLE item; 应该有助于确认您指的是您认为的表,并且该表已在其上定义了您期望的约束。

    如果您绝对确定该表确实包含UNIQUE 约束的重复条目(如果id 列中有重复项,则以下语句将返回TRUE),您可以尝试使用myisamchk执行一些表维护。

    SELECT EXISTS (SELECT * FROM item GROUP BY id HAVING COUNT(*) > 1);
    

    【讨论】:

      猜你喜欢
      • 2023-02-06
      • 2010-10-07
      • 2017-11-25
      • 1970-01-01
      • 1970-01-01
      • 2013-11-23
      • 2016-06-10
      • 2015-05-16
      • 2015-07-30
      相关资源
      最近更新 更多