在我的项目中,我需要在同一个表中找到基于旧版和新版的差异任务。
id | task | latest_Rev
1 A N
1 B N
2 C Y
2 A Y
2 B Y
预期结果:
id | task | latest_Rev
2 C Y
所以我尝试了以下查询
Select new.*
from Rev_tmp nw with (nolock)
left outer
join rev_tmp old with (nolock)
on nw.id -1 = old.id
and nw.task = old.task
and nw.latest_rev = 'y'
where old.task is null
当我的表有超过20k的记录时,这个查询需要更多的时间吗? 如何减少时间?
在我的公司中不允许使用子查询
答案 0 :(得分:5)
使用LAG
功能删除自我加入
SELECT *
FROM (SELECT *,
CASE WHEN latest_Rev = 'y' THEN Lag(latest_Rev) OVER(partition BY task ORDER BY id) ELSE NULL END AS prev_rev
FROM Rev_tmp) a
WHERE prev_rev IS NULL
答案 1 :(得分:0)
您可以尝试此查询(将左外部替换为不存在)
Select *
from Rev_tmp nw
where nw.latest_rev = 'y' and not exists
(
select * from rev_tmp old
where nw.id -1 = old.id and nw.task = old.task
)
答案 2 :(得分:0)
我的回答是
如果查看查询,真正减少结果集的唯一值是latest_rev='Y'
。如果你要消除这种情况,你肯定会得到一个表扫描。所以我们希望使用索引来评估该条件。不幸的是,一个只是重视“Y”和“N”的字段可能会被忽略,因为它的选择性很差。如果您哄骗SQL Server使用它,那么可能会获得更好的性能。如果latest_rev
上的索引被称为idx_latest_rev
,请尝试以下操作:
Set transaction isolated level read uncommitted
Select new.*
from Rev_tmp nw with (index(idx_latest_rev))
left outer
join rev_tmp old
on nw.id -1 = old.id
and nw.task = old.task
where old.task is null
and nw.latest_rev = 'y'