2012-08-30 78 views
1

試圖通過使用INSERT INTO SELECT和連接兩個源表來填充空的MySQL表選擇。想忽略插入定義爲UNIQUE KEY基於兩個目標表列重複行的,但出於某種原因,複製基於這兩個列的行尚未插入。mySQL的INSERT忽略與唯一鍵不工作

目標表的定義:

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 

重複行被插入項目類似以下內容:

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 

我在想什麼?

在此先感謝!

+0

你確定你想加入'tblOrder'到'tblItem'而不是其他方式嗎? – Kermit

+0

有區別嗎?它會被編碼如下: FROM tblItem INNER JOIN tblOrder ON tblOrder.ID = tblItem.orderID – pseudonymo

回答

3

嘗試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 
0

這裏是我的想法。

你似乎是插入一個ID爲AUTO_INCREMENT場。我會建議讓你的item表分配ID。如果我正確閱讀本手冊,則使用IGNORE將使錯誤無效成爲警告並讓語句繼續。在執行INSERT時,這可能會忽略表格中的關鍵限制。

0

CREATE TABLE Syntax作爲下記載:

UNIQUE索引創建,使得索引中的所有值必須是不同的約束。

您有一個在列(item_id,account_id)上定義的複合索引,所以約束條件只要求每個記錄都有這兩列的不同組合。

在你上面的例子,這似乎違反此約束的唯一記錄是:

 
+------+---------+------------+---------------------+---------------------+ 
| id | item_id | account_id |  creation_date | modification_date | 
+------+---------+------------+---------------------+---------------------+ 
| 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 | 
+------+---------+------------+---------------------+---------------------+ 

然而,這些記錄似乎也違反了idPRIMARY KEY約束(即它們似乎是相同的記錄)。這是不可能的,你所顯示的輸出確實是從您已經定義了item表的摘錄:你幾乎肯定是在看一些其他的表或者查詢的內容。

一個可能的解釋是,您已經定義了一個名稱相同的TEMPORARY TABLE,它隱藏底層item表,其中UNIQUE約束被定義。 SHOW CREATE TABLE item;應有助於確認兩個,你指的是你認爲的表和該表已在其上定義了用戶所期望的約束。

如果你是絕對肯定的是,表中確實含有UNIQUE限制(下面的語句將返回TRUE如果有在id列式兩份),你可以嘗試使用myisamchk執行一些表維護重複的條目。

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