Mysql 如何在2列而不是1列中查找重复项
我有一个MySQL数据库表,其中有两列我感兴趣。单独而言,它们可以各有一个副本,但它们不应同时拥有两个具有相同值的副本 stone_id可以有重复项,只要每个追加收费标题不同,反之亦然。但比如说stone_id=412和upcharge_title=sapphire,这种组合只应该出现一次 这没关系:Mysql 如何在2列而不是1列中查找重复项,mysql,duplicates,Mysql,Duplicates,我有一个MySQL数据库表,其中有两列我感兴趣。单独而言,它们可以各有一个副本,但它们不应同时拥有两个具有相同值的副本 stone_id可以有重复项,只要每个追加收费标题不同,反之亦然。但比如说stone_id=412和upcharge_title=sapphire,这种组合只应该出现一次 这没关系: stone_id = 412 upcharge_title = "sapphire" stone_id = 412 upcharge_title = "ruby" 这不好: stone_id =
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,您应该在这两个字段之间设置一个复合键。这将要求每行具有唯一的stone_id和upcharge_标题 要查找现有的重复项,请尝试以下方法:
select stone_id,
upcharge_title,
count(*)
from your_table
group by stone_id,
upcharge_title
having count(*) > 1
要查找重复项,请执行以下操作:
select stone_id, upcharge_title from tablename group by stone_id, upcharge_title having count(*)>1
要约束以避免将来出现这种情况,请在这两个字段上创建一个复合唯一键。您可以找到类似的重复项
Select
stone_id, upcharge_title, count(*)
from
particulartable
group by
stone_id, upcharge_title
having
count(*) > 1
顺便说一句,表上的复合唯一约束将首先防止这种情况发生
ALTER TABLE table
ADD UNIQUE(stone_id, charge_title)
这是有效的T-SQL。不太清楚MySQL。这篇文章对我有所帮助,但我也想知道如何删除和保留其中一行。。。这里有一个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是保留单行的原因
谢谢大家我发现使用ALTER IGNORE添加一个unqiue索引很有帮助,它可以删除重复项并强制执行唯一记录,这听起来像是您想要做的。所以语法应该是:
ALTER IGNORE TABLE `table` ADD UNIQUE INDEX(`id`, `another_id`, `one_more_id`);
这有效地添加了唯一约束,这意味着您将永远不会有重复的记录,而忽略将删除现有的重复记录
您可以在此处阅读有关eh ALTER IGNORE的更多信息:
更新:@Inquisitive通知我,在MySql>5.5的版本中,这可能会失败:
它在MySQL>5.5和InnoDB表上失败,在Percona中失败是因为
他们的InnoDB快速索引创建功能[.在本例中
首先运行set session old_alter_table=1,然后运行上述命令
行吗
更新-在5.7中删除了ALTER IGNORE
从
从MySQL 5.6.17开始,IGNORE子句已被弃用,它的使用
生成警告。忽略在MySQL 5.7中被删除
MySQL开发人员的一个建议是:
按唯一字段分组并如上所示删除
创建新表,添加唯一索引,使用INSERT IGNORE,例如:
但是,根据您表格的大小,这可能不太实际忽略null和blank对我来说很有效。两个不同的电子邮件列:
SELECT *
FROM members
WHERE email IN (SELECT soemail
FROM members
WHERE NOT Isnull(soemail)
AND soemail <> '');
非常感谢,你能告诉我如何删除除一个副本以外的所有副本吗?以及如何在phpmyadmin中设置compisite密钥。谢谢!!!我认为这是可行的,但在我先删除副本之前它不会让我这样做。谢谢。谢谢,这确实选择了副本。你能告诉我如何删除副本,但在当然谢谢!!一种方法是获取所有不同的数据并重新创建表。@John Isaacks:如果没有其他字段可以区分它们,即所有字段都是重复的,那么您必须删除两行并重新创建一行。一种方法是将重复项复制到表的副本中,从原始字段中删除它们,&从副本中重新插入不同的行。这在postgres 8.1上不起作用,有人能帮我一下吗?非常感谢,您分组的顺序重要吗?ALTER IGNORE TABLE TABLE ADD UNIQUE INDEX INDEX\u namestone\u id,charge\u title将删除重复行,只留下一对唯一的行。是的,但至少下次您知道。我有同样的问题,并认为与其他人分享是件好事。我只是取笑它晚了3年。真的很高兴你分享了。因此加1。我想这会任意删除其中一个重复项,因此确保每行之间没有可能有用的不同数据。即使晚了2年,答案也为+1。我意外地发现ally删除了一个复合密钥,这是一个救命稻草。谢谢。我尝试了一些重复查找技术,但没有一种这么简单和快速。谢谢你分享这个方法。
SELECT *
FROM members
WHERE email IN (SELECT soemail
FROM members
WHERE NOT Isnull(soemail)
AND soemail <> '');