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