您好我有一个存储过程,用于在搜索时获取记录。此过程返回数百万条记录。但是,在搜索过程中发现了一个错误,当某些条件满足时,它也会在某些情况下返回重复记录。我找到了它返回重复记录的错误:下面是有问题的查询:
With cteAutoApprove (AcctID, AutoApproved,DecisionDate)
AS (
select
A.AcctID,
CAST(autoEnter AS SMALLINT) AS AutoApproved,
DecisionDate
from
(
SELECT
awt.AcctID,
MIN(awt.dtEnter) AS DecisionDate
FROM
dbo.AccountWorkflowTask awt
JOIN dbo.WorkflowTask wt ON awt.WorkflowTaskID = wt.WorkflowTaskID
Join Task T on T.TaskID = wt.TaskID
WHERE
(
(T.TaskStageID = 3 and awt.ReasonIDExit is NULL)
OR (wt.TaskID IN (9,15,201,208,220,308,319,320,408,420,508,608,620,1470,1608,1620))
)
GROUP BY
awt.AcctID
) A
Join AccountWorkflowTask awt1
on awt1.dtEnter=A.DecisionDate and awt1.AcctID=a.AcctID
),
由于awt1.dtEnter = A.DecisionDate上的条件,此CTE返回重复记录,某些帐户的dtEnter完全相同。这是它返回重复记录的原因。
我的问题是我应该用什么来阻止这种情况。我不能在这里使用Distinct,因为它肯定会减慢搜索过程。我应该使用Rank或Dense Rank以便优化它并且查询花费更少的时间来执行结果?还是其他一些技巧?请帮忙,因为我实际上被困在这里
答案 0 :(得分:1)
看起来它确实是row_number的一个很好的候选者(不是排名,在相同的acctid上有相同的日期,你还有多个记录) 显然,我不能在这里测试查询,但是要对它进行测试:
select
A.AcctID,
CAST(autoEnter AS SMALLINT) AS AutoApproved,
DecisionDate
from
(
SELECT
awt.AcctID,
awt.dtEnter AS DecisionDate,
autoEnter,
row_number() over (partition by awt.acctid order by awt.dtEnter) rnr
FROM
dbo.AccountWorkflowTask awt
JOIN dbo.WorkflowTask wt ON awt.WorkflowTaskID = wt.WorkflowTaskID
Join Task T on T.TaskID = wt.TaskID
WHERE
(
(T.TaskStageID = 3 and awt.ReasonIDExit is NULL)
OR (wt.TaskID IN (9,15,201,208,220,308,319,320,408,420,508,608,620,1470,1608,1620))
)
) A
where rnr = 1
这样,不再需要group by:获取第一个日期由row_number完成。也不是第二个连接,子查询已经包含所有数据(并且优化器足够智能,不会对它不需要的行做任何事情)
PS。因为sql server窗口函数工作效率非常高,使用row_number而不是min() - join构造,即使没有双行,也很可能获得性能提升。