如何在2列而不是1列中查找重复项

时间:2009-03-13 13:18:11

标签: mysql duplicates

我有一个MySQL数据库表,有两列让我感兴趣。单独地,他们每个人都可以有重复,但他们不应该有两个具有相同价值的重复。

只要每个stone_id标题不同,

upsharge就可以有重复项,反之亦然。但比如说stone_id = 412和upcharge_title =“蓝宝石”这种组合应该只出现一次。

没关系:

stone_id = 412 upcharge_title = "sapphire"
stone_id = 412 upcharge_title = "ruby"

这不行:

stone_id = 412 upcharge_title = "sapphire"
stone_id = 412 upcharge_title = "sapphire"

是否有查询会在两个字段中找到重复项?如果可能的话,有没有办法将我的数据库设置为不允许这样做?

我使用的是MySQL 4.1.22版本

7 个答案:

答案 0 :(得分:167)

您应该在两个字段之间设置复合键。这将需要每行一个独特的stone_id和upcharge_title。

就查找现有重复项而言,请尝试以下方法:

select   stone_id,
         upcharge_title,
         count(*)
from     your_table
group by stone_id,
         upcharge_title
having   count(*) > 1

答案 1 :(得分:32)

我发现使用“ALTER IGNORE”添加unqiue索引很有帮助,它可以删除重复项并强制执行您想要的独特记录。所以语法是:

ALTER IGNORE TABLE `table` ADD UNIQUE INDEX(`id`, `another_id`, `one_more_id`);

这有效地添加了唯一约束,这意味着您永远不会有重复记录,IGNORE会删除现有的重复记录。

您可以在此处阅读更多关于eh ALTER IGNORE的信息:http://mediakey.dk/~cc/mysql-remove-duplicate-entries/

更新:@Inquisitive通知我,MySql版本可能会失败> 5.5:

  

它在MySQL上失败> 5.5和InnoDB表,以及Percona中的   他们的InnoDB快速索引创建功能[http://bugs.mysql.com/bug.php?id=40344]。在这种情况下   首先运行set session old_alter_table=1然后运行上面的命令   会很好吗

更新 - ALTER IGNORE已删除5.7

来自docs

  

从MySQL 5.6.17开始,不推荐使用IGNORE子句及其使用   生成警告。在MySQL 5.7中删除了IGNORE。

其中一个MySQL开发者提供two alternatives

  • 按唯一字段分组并删除如上所示
  • 创建新表,添加唯一索引,使用INSERT IGNORE,例如:
CREATE TABLE duplicate_row_table LIKE regular_row_table;
ALTER TABLE duplicate_row_table ADD UNIQUE INDEX (id, another_id);
INSERT IGNORE INTO duplicate_row_table SELECT * FROM regular_row_table;
DROP TABLE regular_row_table;
RENAME TABLE duplicate_row_table TO regular_row_table;

但是根据你桌子的大小,这可能不实用

答案 2 :(得分:6)

你可以找到像这样的重复...

Select
    stone_id, upcharge_title, count(*)
from 
    particulartable
group by 
    stone_id, upcharge_title
having 
    count(*) > 1

答案 3 :(得分:4)

要查找重复项:

select stone_id, upcharge_title from tablename group by stone_id, upcharge_title having count(*)>1

要限制在将来避免这种情况,请在这两个字段上创建复合唯一键。

答案 4 :(得分:3)

顺便说一句,表上的复合唯一约束会阻止这种情况发生。

ALTER TABLE table
    ADD UNIQUE(stone_id, charge_title)

(这是有效的T-SQL。不确定MySQL。)

答案 5 :(得分:0)

这篇SO帖子对我有帮助,但我也想知道如何删除并保留其中一行......这是一个删除重复行并保留一行的PHP解决方案(在我的情况下,只有2列和它是一个清除重复类别关联的功能)

$dupes = $db->query('select *, count(*) as NUM_DUPES from PRODUCT_CATEGORY_PRODUCT group by fkPRODUCT_CATEGORY_ID, fkPRODUCT_ID having count(*) > 1');
if (!is_array($dupes))
    return true;
foreach ($dupes as $dupe) {
    $db->query('delete from PRODUCT_CATEGORY_PRODUCT where fkPRODUCT_ID = ' . $dupe['fkPRODUCT_ID'] . ' and fkPRODUCT_CATEGORY_ID = ' . $dupe['fkPRODUCT_CATEGORY_ID'] . ' limit ' . ($dupe['NUM_DUPES'] - 1);
}

(限制NUM_DUPES - 1)是保留单行的原因......

感谢所有

答案 6 :(得分:0)

这对我有用(忽略空值和空白)。两个不同的电子邮件列:

SELECT * 
FROM   members 
WHERE  email IN (SELECT soemail 
                 FROM   members 
                 WHERE  NOT Isnull(soemail) 
                        AND soemail <> '');