sql - 从非常大的表中删除重复的子集
问题描述
我正在使用的数据相当复杂,所以我将提供一个更简单的示例,希望可以将其扩展到我正在处理的内容。
注意:我已经找到了一种方法,但它非常慢且不可扩展。它在小型数据集上效果很好,但如果我将它应用到它需要运行的实际表上,那将需要很长时间。
我需要删除表中整个重复的数据子集。删除重复的行很容易,但我一直在寻找一种有效的方法来删除重复的子集。
例子:
GroupID Subset Value
------- ---- ----
1 a 1
1 a 2
1 a 3
1 b 1
1 b 3
1 b 5
1 c 1
1 c 3
1 c 5
2 a 1
2 a 2
2 a 3
2 b 4
2 b 5
2 b 6
2 c 1
2 c 3
2 c 6
因此,在此示例中,从 GroupID 1 中,我需要删除子集“b”或子集“c”,这并不重要,因为两者都包含值 1、2、3。对于 GroupID 2,没有一个集合是重复的,所以没有一个被删除。
这是我用来小规模解决这个问题的代码。它工作得很好,但是当应用于 10+ 百万条记录时......你可以想象它会很慢(我后来被告知记录的数量,我得到的样本数据要小得多)......:
DECLARE @values TABLE (GroupID INT NOT NULL, SubSet VARCHAR(1) NOT NULL, [Value] INT NOT NULL)
INSERT INTO @values (GroupID, SubSet, [Value])
VALUES (1,'a',1),(1,'a',2),(1,'a',3) ,(1,'b',1),(1,'b',3),(1,'b',5) ,(1,'c',1),(1,'c',3),(1,'c',5),
(2,'a',1),(2,'a',2),(2,'a',3) ,(2,'b',2),(2,'b',4),(2,'b',6) ,(2,'c',1),(2,'c',3),(2,'c',6)
SELECT *
FROM @values v
ORDER BY v.GroupID, v.SubSet, v.[Value]
SELECT x.GroupID, x.NameValues, MIN(x.SubSet)
FROM (
SELECT t1.GroupID, t1.SubSet
, NameValues = (SELECT ',' + CONVERT(VARCHAR(10), t2.[Value]) FROM @values t2 WHERE t1.GroupID = t2.GroupID AND t1.SubSet = t2.SubSet ORDER BY t2.[Value] FOR XML PATH(''))
FROM @values t1
GROUP BY t1.GroupID, t1.SubSet
) x
GROUP BY x.GroupID, x.NameValues
我在这里所做的只是按 GroupID 和 Subset 进行分组,并将所有值连接到一个逗号分隔的字符串中……然后将其分组到 GroupID 和 Value 列表中,然后取 MIN 子集。
解决方案
我会用这样的东西:
;with cte as
(
select v.GroupID, v.SubSet, checksum_agg(v.Value) h, avg(v.Value) a
from @values v
group by v.GroupID, v.SubSet
)
delete v
from @values v
join
(
select c1.GroupID, case when c1.SubSet > c2.SubSet then c1.SubSet else c2.SubSet end SubSet
from cte c1
join cte c2 on c1.GroupID = c2.GroupID and c1.SubSet <> c2.SubSet and c1.h = c2.h and c1.a = c2.a
)x on v.GroupID = x.GroupID and v.SubSet = x.SubSet
select *
from @values
推荐阅读
- bash - 如何从 bash 脚本将文件上传到 Google Drive?
- python-3.x - 如何使用Huggingface T5模型测试翻译任务?
- python - python,while循环,函数内部调用的函数
- firebase - Firestore 查询中是否可以使用通配符功能?
- jenkins - 如何正确包装 Jenkins 插件功能,例如 copyArtifacts?
- android - 手动卸载后无法运行应用程序
- mysql - MYSQL检查一个表中存在的每个项目是否存在于另一个表中
- node.js - 使用 ExpressJS 进行身份验证
- c++ - C++ SDL 项目的 Makefile
- python - 如何在 Keras 中控制微分链式法则