125

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

stone_id只要每个upsharge标题不同,就可以有重复,反之亦然。但是例如说stone_id= 412 和upcharge_title= "sapphire" 组合应该只出现一次。

还行吧:

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

4

7 回答 7

234

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

至于找到现有的重复,试试这个:

select   stone_id,
         upcharge_title,
         count(*)
from     your_table
group by stone_id,
         upcharge_title
having   count(*) > 1
于 2009-03-13T13:20:26.967 回答
36

我发现使用“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 中删除

文档

从 MySQL 5.6.17 开始,不推荐使用 IGNORE 子句,并且它的使用会产生警告。IGNORE 在 MySQL 5.7 中被删除。

MySQL 开发人员之一提供了两种选择

  • 按唯一字段分组并删除,如上所示
  • 创建一个新表,添加一个唯一索引,使用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;

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

于 2012-06-14T22:44:46.260 回答
9

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

Select
    stone_id, upcharge_title, count(*)
from 
    particulartable
group by 
    stone_id, upcharge_title
having 
    count(*) > 1
于 2009-03-13T13:22:05.323 回答
5

要查找重复项:

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

为了避免将来发生这种情况,请在这两个字段上创建一个复合唯一键。

于 2009-03-13T13:21:46.090 回答
5

顺便说一句,表上的复合唯一约束将首先防止这种情况发生。

ALTER TABLE table
    ADD UNIQUE(stone_id, charge_title)

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

于 2009-03-13T13:36:04.493 回答
1

这篇 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);
}

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

谢谢大家

于 2010-08-19T21:34:46.363 回答
0

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

SELECT * 
FROM   members 
WHERE  email IN (SELECT soemail 
                 FROM   members 
                 WHERE  NOT Isnull(soemail) 
                        AND soemail <> ''); 
于 2021-05-03T00:02:42.310 回答