也许这个头衔并不是真正的启发,但我不能用一个不那么做作的人来。这是我的问题:
我正在使用具有看起来像数据的表
id cId ver active
1 100 1 0
2 100 2 1
3 100 3 1
4 200 1 0
5 200 2 1
6 300 1 1
对于此表,Id是PK,cId标识客户端。基本上我们存储版本历史。
我试图解决的问题是更新数据库以仅为每个客户端最高[ver]的最新版本设置active = 1。 (示例中包含cId 100的客户端)
现在,我已设法编写以下查询,该查询为我提供了数据
select t.id, t.cId,t.version
from (select *
from comp.Clients a
where a.ver = (select max(b.ver) from comp.Clients b where a.cId=b.cIdentifier)
) t
从那时起,我的解决方案是将该查询插入游标上,对于游标上的每个记录,我会将表更新为active = 0,并将active = 1更新为当前记录。
事情是游标是它们是什么,有什么东西给我一个体面的表现在这里?我对CTE并不好,所以我无法想出一个围绕它的解决方案。实际表有大约10k记录和大约50个字段。
你应该找到每个ver
的最后一个CId
然后更新你的表
select cId,Max(ver) as MaxVer into #tmpTable from comp.Clients group by cid
update c
set active = case when t.cId is not null then 1 else 0 end
from comp.Clients c left join #tmpTable t on t.CId=c.CId and t.MaxVer=c.ver
而不是使用游标,使用2更新。一个用于将值更新为0,另一个用于将客户端ID的最新版本设置为1.这应该足够了。
使用可更新的CTE:
with toupdate as (
select c.*,
max(ver) over (partition by CId) as max_ver
from comp.Clients c
)
update toupdate
set active = (case when max_ver = ver then 1 else 0 end);
如果您愿意,可以添加where
子句来限制要更新的行数:
where active <> (case when max_ver = ver then 1 else 0 end)