我有一个包含个人和一些细节的大型数据集。该数据集包含大量重复项,并且大量记录基于它们的一个特征彼此“相关”。为确保链接正确的记录,3个功能中的2个匹配将被计为链接。每个人都需要链接到所有可能的记录,并且每个记录都将被分配一个clusterId。
我有以下数据集结构:
+--+----+----+----+
|id|col1|col2|col3|
+--+----+----+----+
|1 |A |B |C |
+--+----+----+----+
|2 |A |B |D |
+--+----+----+----+
|3 |A |Z |D |
+--+----+----+----+
Id 1将链接到id 2(因为col1和col2是相同的),id 2将链接到id 3(因为col1和col3是相同的)。链接id 1和2为这个“集群”增加了一些信息,在建立了链接之后,id 3应属于该集群。
数据集非常大(2800万条记录),我不知道这会让我在合理的时间范围内建立这些关系。
任何想法解决这个问题的最快捷,最优雅的方式是什么?
答案 0 :(得分:0)
有了那么多数据,创建关系可能会很慢,但是如果您的列被编入索引并且您有一个快速的服务器,那么它可能不会太糟糕。创建一个表来存储关系。这个SQL应该填充关系。
CREATE TABLE RelationshipTable
([id1] int, [id2] int,[cluster] int);
INSERT INTO RelationshipTable
SELECT a.id,b.id,NULL
FROM TestTable a
LEFT JOIN TestTable b ON a.id<>b.id AND (
(
((a.col1 is null and b.col1 is null) or a.col1=b.col1)
and ((a.col2 is null and b.col2 is null) or a.col2=b.col2)
)
OR
(
((a.col1 is null and b.col1 is null) or a.col1=b.col1)
and ((a.col3 is null and b.col3 is null) or a.col3=b.col3)
)
OR
(
((a.col2 is null and b.col2 is null) or a.col2=b.col2)
and ((a.col3 is null and b.col3 is null) or a.col3=b.col3)
)
)
DECLARE @UpdateId INT
DECLARE @ClusterId INT
SET @ClusterId=0
WHILE EXISTS(
SELECT *
FROM RelationshipTable
WHERE [cluster] IS NULL
)
BEGIN
SET @ClusterId=@ClusterId+1
SELECT
@UpdateId=[id1]
FROM RelationshipTable
WHERE [cluster] IS NULL
UPDATE RelationshipTable
SET [cluster]=@ClusterId
WHERE ID1=@UpdateId
OR ID2=@UpdateId
WHILE @@Rowcount>0
BEGIN
UPDATE RelationshipTable
SET [cluster]=@ClusterId
WHERE [cluster] IS NULL
AND
(
ID1 IN (
SELECT ID1
FROM RelationshipTable
WHERE [cluster]=@ClusterId
UNION
SELECT ID2
FROM RelationshipTable
WHERE [cluster]=@ClusterId
)
OR ID2 IN (
SELECT ID1
FROM RelationshipTable
WHERE [cluster]=@ClusterId
UNION
SELECT ID2
FROM RelationshipTable
WHERE [cluster]=@ClusterId
)
)
END
END
select * from RelationshipTable