【问题标题】:Remove duplicates records in a MySQL table with key but not primary key删除带有键但不是主键的 MySQL 表中的重复记录
【发布时间】:2013-10-22 19:54:34
【问题描述】:

我需要从 MyISAM 格式的 MySQL 表中删除重复记录(仅保留一份)。我在 Stackoverflow 中阅读了许多关于类似问题的问题,但人们总是使用 ID 字段作为唯一 ID 或类似的,而我没有这个字段,因为我的“密钥”可能被复制。我想删除“Fecha”和“Equip”重复的行。

CREATE TABLE `pfc` (
`Fecha` datetime NOT NULL,
`Equip` int(10) unsigned NOT NULL,
`Value` double NOT NULL,
KEY `Fecha` (`Fecha`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AVG_ROW_LENGTH=21 ROW_FORMAT=FIXED;

一个示例表数据:

Fecha              | Equip | Value 
06/02/2011 0:00:11 |  22   |  29.0
06/02/2011 0:22:11 |  22   |  45.3
06/02/2011 0:00:11 |  22   |  29.0

结果应该是:

Fecha              | Equip | Value 
06/02/2011 0:00:11 |  22   |  29.0
06/02/2011 0:22:11 |  22   |  45.3

这种结构是不可能改变的。我不能使用 PRIMARY KEY 或 UNIQUE INDEX 解决方案。创建一个没有重复的临时表然后重命名也是一个糟糕的解决方案,因为 KEY 和另一个参数将会丢失。

谢谢

【问题讨论】:

  • 为什么临时表不是一个糟糕的解决方案?您始终可以重新创建索引。另外,如果Equip和Fecha是重复的,如果值不同,应该选择什么值?
  • 临时表可以工作,但不能将表“new_fc”创建为“Octopus-Paul”,然后将“new_pfc”重命名为“pfc”。如何使用临时表来解决问题?
  • 你不必使用临时表,有更优雅的解决方案。
  • 无温度。表是不可能的。您的表没有 id 并且 MySQL 不支持内部行 id。该表包含两个相同的行 - '06/02/2011 0:00:11|22|29.0'。如何指定应该删除的行?
  • @Devart - 你有 MySQL 不支持内部行 ID 的任何来源吗?仅供参考,这不取决于 MySQL,而是使用了存储引擎。

标签: mysql duplicate-removal


【解决方案1】:
ALTER IGNORE TABLE `pfc` ADD UNIQUE(`Fetcha`, `Equip`);

这将保留它找到的第一条记录并从您的表中删除重复项。

来自 MySQL 手册:

IGNORE 是标准 SQL 的 MySQL 扩展。它控制如何改变 如果新表中的唯一键有重复项,则 TABLE 有效,或者 如果启用严格模式时出现警告。如果 IGNORE 不是 指定,如果重复键错误,副本将中止并回滚 发生。如果指定了 IGNORE,则仅使用第一行 在唯一键上重复。其他冲突的行被删除。 不正确的值被截断为最接近的匹配可接受 价值。

编辑:

要创建表的精确副本,请使用以下命令:

CREATE TABLE table_copy SELECT * FROM pfc;

这将复制表结构和数据。之后,运行 ALTER 命令添加 UNIQUE 约束并过滤掉重复的记录。

【讨论】:

  • 对不起,我已经说过了,我不能使用 UNIQUE,因为格式表是不可触摸的。
  • 所以创建表的副本,添加约束,过滤结果,截断原始表并用复制表的内容填充它。总共大约需要 2 分钟的工作时间。你可以截断或删除,对吧?
  • 如果格式相同,我创建表格的副本,但我不知道该怎么做。
  • 抱歉,副本不准确。我得到一个像这样的表:CREATE TABLE pfc_new` (Fecha datetime NOT NULL, Equip int(10) unsigned NOT NULL, Value double NOT NULL, ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
  • 所以您是说计算机在被指示创建目标表的精确副本后,未能执行此操作并执行了其他操作?现在怎么可能? :)
【解决方案2】:

只是作为一个测试,试试这个看看是不是你想要的

CREATE TABLE new_pfc AS
SELECT * FROM pfc GROUP BY fecha, equip

【讨论】:

  • 正如我所说,创建一个临时的“new_pfc”是一个糟糕的解决方案,因为索引和其他格式都丢失了。我需要避免更改表格格式。
【解决方案3】:
DELETE n1 FROM pfc n1, pfc n2 WHERE n1.Fecha = n2.Fecha AND n1.Equip=n2.Equip AND n1.Value=n2.Value

【讨论】:

    猜你喜欢
    • 2010-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-13
    • 2019-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多