我需要从表t1中找到具有唯一(TRAN_ID,CMTE_ID)对的行,其中TRAN_ID和CMTE_ID是其中的两列。然后我想将这些行插入表uniques
问题是表uniques似乎最终包含重复的对。
注意:表t1是使用InnoDb引擎创建的,然后更新为使用MyISAM引擎,以加速group by和join操作。t1有1.3亿行。
下面是我的创建查询:

DROP TABLE IF EXISTS uniques;
CREATE TABLE `uniques` (
   `CMTE_ID` varchar(9) DEFAULT '',
   `TRAN_ID` varchar(32) DEFAULT '',
   KEY `TRAN_INDEX` (`TRAN_ID`,`CMTE_ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

然后运行查询并插入到uniques
LOCK TABLES  uniques write, t1 write;

INSERT INTO uniques
     SELECT TRAN_ID,CMTE_ID
           FROM t1
           GROUP BY TRAN_ID,CMTE_ID
           HAVING count(*) = 1;
UNLOCK TABLES;

在这一点上,我希望uniques用具有唯一(TRAN_ID,CMTE_ID)对的行填充。但是,当我跑的时候
SELECT * FROM uniques
    GROUP BY TRAN_ID,CMTE_ID
    having count(*) > 1;

我还有一长串的行。发生什么事?

最佳答案

你可能想在这对上加一个unique的禁忌,以防出现uniques。
首先猜测是运算符错误,或者表已经有数据。打折这些,还有另一种可能。字段的类型为:

`CMTE_ID` varchar(9) DEFAULT '',
`TRAN_ID` varchar(32) DEFAULT '',

也许这些数据不够大,所以当加载到表中时,数据实际上被截断了。这只是个主意。你的过程似乎很好。
编辑:
事实上,我认为最后一个是正在发生的事情。您的insert查询相当于:
INSERT INTO uniques(CMTE_ID, TRAN_ID)
     SELECT TRAN_ID,CMTE_ID
     FROM t1
     GROUP BY TRAN_ID,CMTE_ID
     HAVING count(*) = 1;

请注意,列顺序不同,因此TRAN_ID被加载到CMTE_ID中,反之亦然。因为类型不同,CMTE_ID可能被截断。
这是一个很好的教训,说明为什么您应该始终在insert语句中包含列列表。

10-07 15:59