【发布时间】:2015-03-22 07:42:29
【问题描述】:
我正在尝试更新一个表,以便我标记任何具有重复名称条目的条目。我做了一些处理来删除一些常见的前缀和后缀,然后可以使用模糊匹配的 CLR 来运行两个名称。我把它写成一个嵌套游标,目前它需要大约 4 个小时来运行所有记录,因为我必须检查每一行与其他每一行。我读过使用递归 CTE 可以显着提高性能,但是我有点 SQL 菜鸟,不能让它工作。我想我需要将一个递归 CTE 嵌套到另一个中,但不确定如何。
目前我有类似的东西:
;WITH AllOrgs (CompanyId, CompanyRoleId, Name, Recognized, Level)
AS
(
SELECT C.CompanyId, C.CompanyRoleId, C.Name, C.Recognized, 1
FROM Company O
WHERE DuplicateOfCompanyId IS NULL
UNION ALL
SELECT C.CompanyId, C.CompanyRoleId, C.Name, R.Recognized, R.Level + 1
FROM AllOrgs R INNER JOIN Company C
ON C.CompanyId = R.CompanyId
),
DuplicateOrgs (CompanyId, CompanyRoleId, Name, Recognized, Level)
As
(
SELECT * FROM AllOrgs
WHERE Recognized = 0 -- Recognized is what the companies are marked when we are satisfied they aren't incorrect
)
UPDATE O
SET C.DuplicateOfCompanyId = A.CompanyId
FROM Company O JOIN DuplicateOrgs A
ON C.CompanyId = A.CompanyID
WHERE master.dbo.fnClrFuzzyMatch(dbo.fnCleanUpCompanyName(A.Name), dbo.fnCleanUpCompanyName(C.Name))
> @CompanyNameMatchValueThreshold
AND A.CompanyRoleID = C.CompanyRoleId -- Role ID must match as duplicates who provide a different function are fine
但每当我尝试运行它时,我都会收到“语句终止。在语句完成之前,最大递归 100 已用尽。”所以我显然在做一些愚蠢的事情。
【问题讨论】:
-
递归并不比游标好多少。如果您想将一行与具有相同 CompanyID 的任何其他行进行比较,请在 CompanyID 上执行自连接,条件是排除将一行连接到自身(例如 A.ID B.ID),然后将模糊匹配功能应用于结果
-
对于该错误消息,您需要 OPTION (MAXRECURSION 0);如果您通过大量数据进行递归,这可能会使您的服务器崩溃
-
你能展示数据示例吗?您确定完全不使用游标或递归查询就不能做同样的事情吗?
-
作为一个快速数据示例,您有两行:ID|RoleID|Name|Recognized|IsduplicateOf 1|1|Quickimart|1|NULL 2|1|Quickimart Ltd|0|NULL 我想更新第二行作为第一行的副本,我希望能够对表中的每一行针对其他每一行执行此操作。
标签: sql tsql recursion sql-server-2012 common-table-expression