php - 3800 万条记录 - 根据列名删除重复行并仅保留一条

标签 php mysql

免责声明 - 我已经阅读了许多精彩的问题及其答案,并且也尝试过。唯一的问题是,考虑到数据库的大小,系统会陷入“加载”状态,并且只是坐在那里。通过查看总行数,我发现发生了变化,但当它不发出警告或分段执行时,变化并不重要。我确实有一个很好的想法,可以调整可用代码并使其工作,但我还不是全职/高级开发人员(还!)

问题 - 我一直在开发一个包含产品信息但具有重复值的数据库(在将多个 CVS 导入数据库时​​不使“产品代码”列唯一是愚蠢的) 。我需要帮助删除“产品代码”的重复基础,但想“保留一个”,它在“规范”列下具有最大信息。

数据库 - MySQL 总记录 - 3600 万+ 总列 - 不超过 15(但相关性较低) 问题 - 多个重复值基于“产品代码”,但在“规范列”中保留一个具有最大字符数的值

数据库详细信息; 表名-pro

列名称如下; 产品ID - VARCHAR, manPartId - VARCHAR, 规范 - 文本

到目前为止,我已经选择了以下代码并进行了尝试,但系统卡在“正在加载”并且没有任何反应。我认为这是因为它拥有大量记录。

我尝试在 phpMyAdmin“SQL”部分运行的代码是;

--------------------------------------------
      delete pro
      from pro
      inner join (
         select max(productid) as lastId, manPartId
           from pro
          group by manPartId
         having count(*) > 1) duplic on duplic.manPartId = pro.manPartId
         where pro.productid < duplic.lastId;
--------------------------------------------

以上代码已根据 MySQL delete duplicate records but keep latest 上的原始代码进行了调整。

请帮助并理解我哪里出了问题。另请注意,我确实了解上述代码仅适用于“删除所有内容但保留一个”,而不是“在规范列中保留一个基本总文本可用”。

非常感谢!

编辑 - 根据 aendererei 的建议,我对细节进行了一些编辑。

-------------------------------------------------------
productid  | manPartId    |  specification 
-------------------------------------------------------
1            ABC1           5MP camera, 2500 MaH, Steel body
2            ABC2           2MP camera, Steel body
3            ABC3           5MP, 6500 MaH, Red
4            ABC1           2500 MaH, Steel body
5            ABC2           5MP camera, plastic body
6            ABC4           5MP camera, 2500 MaH, Steel body
7            ABC5           15MP camera, 4500 MaH 
8            ABC2           5MP camera
9            ABC3           15MP, 6500 MaH, Blue body
10           ABC5           2500 MaH, Steel body
-------------------------------------------

在上述情况下,我正在考虑删除重复的基础 manPartId,但希望保留一条在规范字段中具有最大(字符)的记录。

运行查询后,我希望看到以下更新后的数据具有唯一的 manPartId,且规范列下有最大文本;

-------------------------------------------------------
productid  | manPartId    |  specification 
---------------------------------------------------------------
1            ABC1           5MP camera, 2500 MaH, Steel body
5            ABC2           5MP camera, plastic body
6            ABC4           5MP camera, 2500 MaH, Steel body
7            ABC5           15MP camera, 4500 MaH, Long life
9            ABC3           15MP, 6500 MaH, Blue body
---------------------------------------------------------------

如果还是不清楚,请接受我的歉意!

最佳答案

首先,根据,找到所有部分的最长长度(查询#1)

SELECT 
      manPartID,
      MAX( CHAR_LENGTH( specification )) longestLength
   from
      pro
   group by
      manPartID

以此为基准,现在查找具有相同最长长度的所有部分。但如果有多个长度完全相同的产品,则需要选择一个,例如要保留第一个 ProductID 或最近的 ProductID...(查询#2)

SELECT
      p.manPartID,
      MAX( p.productid ) as ProductID
   from
      pro p
         JOIN
            ( Entire Query #1 above ) byLen
          ON p.manPartID = byLen.manPartID
          AND char_length( p.specification ) = byLen.LongestLength
   group by
      p.manPartID

因此,此时,基于最长的规范,对于单个“manPartID”,您只有一个“ProductID”...现在,您可以从主表中删除它不是上述内容之一的内容,如下所示。我正在对 #2 查询执行 LEFT JOIN,因为我希望比较所有记录并仅删除在保留结果集中未找到的记录。

DELETE FROM Pro
   LEFT JOIN (entire query #2 above) Keep
      ON Pro.ProductID = Keep.ProductID
   where Keep.ProductID IS NULL

现在,在包含 3600 万条记录的表上,您可能希望在丢失数据之前确保上述工作正常进行。因此,我不会删除,而是创建一个新的产品辅助表并将其插入其中,以确认您得到了您所希望的内容...

INSERT INTO SomeTempTable
SELECT p1.*
   from Pro p1
      JOIN ( query #2 above ) Keep
         ON p1.ProductID = Keep.ProductID

请注意,这是一个 JOIN(不是删除中使用的左连接),因为我只想要那些我希望保留的产品

我确信表上还有所描述的其他元素,因此为了提高查询性能,我将在您的“Pro”duct 表上有以下索引。

(manPartID, specification, productID)

这样,工作就可以通过索引完成,而不必遍历每条记录的所有数据页。

关于php - 3800 万条记录 - 根据列名删除重复行并仅保留一条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44917104/

相关文章:

php - nginx 在提供静态文件时调用外部脚本(传递请求信息)?

php - PDO MySQL SQLSTATE[42000]

php - 为什么会有人使用 printf 来输出 html,而不是将 PHP 分解成实际的 html?

MySQL在数组中按键搜索json值

php - UTF-8贯穿始终

mysql - 从 SQL 表创建键值对

mysql - 选择mysql中具有不同帖子ID的所有帖子

c# - 如何以可读格式从 MySQL 获取数据 C#

javascript - 如何通过 JavaScript 设置 PHP 变量以隐藏特定视口(viewport)宽度的图像

php - Joomla 3 身份验证以访问 PHP 中的外部应用程序