我要求通过(SSN)或(LName&地址)比较1000万个帐户,并找出属于同一个人(SSN)或家庭成员(姓名和地址)的帐户。同一帐户可以有多个联名账户持有人。因此,查询应该是递归的,以获得与每个帐户持有人匹配的帐户+结果帐户应该进一步应用相同的逻辑。
样本表
AccountNo | Account Holders| SSN
12345678 | Father | 3333333333
12345678 | Mother | 4444444444
23232323 | Son | 5555555555
45454545 | Father | 3333333333
45454545 | Son | 5555555555
45454545 | Daughter | 1111111111
98989898 | wife | 1010101010
98989898 | Son | 5555555555
名称和地址将有其他列。地址比较逻辑很棘手,因此我使用函数来比较两个地址。
最初我使用游标来处理比较逻辑并获得同一组下的所有匹配帐户。但是,它需要花费太多时间,并且预计会运行几天来处理所有1000万条记录。
我正在努力寻找另一种更快的解决方案。我的第一个方法是让所有帐户与SSN匹配并创建组然后我将尝试名称&地址。
我正在尝试使用CTE来获取群组。因此,对于上面的示例,我希望所有上述帐户在同一个groupid下。并且将有其他家庭具有单独的groupid。
第一件事,我收集了所有具有相同SSN的组。现在我想合并多个SSN持有的所有帐户,现在属于不同的组。
这是我用来通过SSN获取小组的初始CTE
;WITH CTE_SGroup AS
(
SELECT
AccountNo, SSN,
DENSE_RANK() OVER (ORDER BY SSN) SGROUPID
FROM
AcctTable
)
现在,我无法获得查询以递归方式合并所有这些帐户。
有关此问题的任何帮助都会有所帮助。
其他: 这是示例。我有这个表和第三列预期列。
Acct# SSNGrp Expected Result
1 4 1
1 5 1
2 6 1
4 2 1
4 4 1
4 6 1
3 7 2
5 7 2
使用帐户1开始处理,前两行将具有相同的组。现在对于所有SSNGrp 4和5从第二列将导致相同的组。然而,SSNgrp 4也属于Acct#4,因此Acct#4的所有3行被分配给相同的组。递归地,由于SSNgrp 6,Accnt 2也将在第1组中。
答案 0 :(得分:1)
MIN OVER
匹配具有相同值的多个行,使用此结果将此结果分配给现有数据并重复该过程,直到不再更新行为止:
-- untested (modified existing Teradata SQL to SQL Server syntax)
DECLARE @activity_count INTEGER
select *,
row_number() over (order by AccountNo) as rn, -- you need a key for the UPDATEs
row_number() over (order by AccountNo) as GroupNo -- matched rows get the same group
into #temp
from tab
set @activity_count = @@ROWCOUNT
while @activity_count > 0 -- recursive part, repeat until no more row UPDATEd
begin
update #temp
set GroupNo = x.newGrp
from
(select rn, SSN,
min(GroupNo) over (partition by SSN) as newGrp -- same SSN
from #temp
) as x
where #temp.rn = x.rn
and #temp.GroupNo <> x.newGrp -- only new group members
set @activity_count = @@ROWCOUNT
update #temp
set GroupNo = x.newGrp
from
(select rn, AccountNo,
min(GroupNo) over (partition by AccountNo) as newGrp -- same AccountNo
from #temp
) as x
where #temp.rn = x.rn
and #temp.GroupNo <> x.newGrp -- only new group members
set @activity_count = @activity_count + @@ROWCOUNT
-- repeat previous UPDATE/SET for any other column to match
end -- while
select dense_rank() over (order by GroupNo) as expectedResult, *
from #temp
order by GroupNo, rn
为了能够包含地址匹配逻辑,您的功能必须将单个地址缩减为简化形式。
答案 1 :(得分:0)
遍历每一行并用光标将其与每一行进行比较将会非常缓慢。为了更容易地找到重复项,我会将它们分组并仅返回带有&gt;的副本。 1组中。这是一个示例:
SELECT AccountNumber, count(1)
FROM foo
GROUP BY AccountNumber
HAVING COUNT(1) > 1
找到重复项后,您就可以开始合并/删除它们了。