【发布时间】:2019-02-09 05:31:47
【问题描述】:
我正在处理的数据相当复杂,所以我将提供一个更简单的示例,希望可以将其扩展到我正在处理的内容。
注意:我已经找到了一种方法,但它非常缓慢且不可扩展。它在小型数据集上效果很好,但如果我将它应用到它需要运行的实际表上,则需要很长时间。
我需要删除表中所有重复的数据子集。删除重复行很容易,但我一直在寻找删除重复子集的有效方法。
例子:
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 子集。
【问题讨论】:
-
您好,您是否尝试同时执行此查询,但使用 off cte ?只是为了比较性能建议。
-
@pascalsanchez 不,我没有,但我会试一试。我想知道是否有办法通过递归 CTE 来实现这一点,但我认为对于大表来说这不会更有效。
标签: sql sql-server tsql