使用了游标,但它很慢并且似乎是 SQL 作业中的一个大瓶颈。基本上,这是一项清理工作,从以前按产品 ID 和帐户可见性分组的特定来源中删除除前 X 配件(按销售排名排序)之外的所有配件。
该命令基本上是在游标循环的每次迭代中构建并exec
手动编辑的。
该vis
列指的是多个租户,其行为类似于位掩码,例如两个租户可能拥有相同的产品。
declare @prodid int
declare @cnt int
declare @vis bigint
declare @cmd varchar(600)
declare @clause varchar(600)
-- find records with more than X excess accessories
declare cur cursor for
select pa.prodid, 'cnt' = count(*), vis from [accessories] pa
group by prodid, vis
having count(*) > X -- e.g. 5
示例输出可能看起来像
prodid cnt vis
123 6 128
234 8 260
345 10 512
在 X=5 的情况下,salesrank
123 的最后 1 项将被删除,234 的最后 3 项和 345 的最后 5 项将被删除。这可以使用DELETE
语句完成,同时在某些嵌套选择中包含分组吗?
open cur
fetch next from cur into @prodid, @cnt, @vis
while @@fetch_status = 0
begin
-- a clause that ends up looking like this:
-- 12345 and vis = 128 -- OR -- 23456 and vis is null
set @clause = convert(varchar(14), @prodid) + ' and vis ' + case
when @vis is null then ' is null '
else ' = ' + cast(@vis as varchar) end
-- delete all but the top X from source=2 and that match prodid and vis
set @cmd = 'delete from [accessories]
where source = 2 and prodid=' + @clause +
' and access_prodid in (select top ' + convert(varchar(5), @cnt - X) +
' access_prodid from [accessories] where prodid = '
+ @clause + ' and source = 2 order by salesrank)'
exec(@cmd)
fetch next from cur into @prodid, @cnt, @vis
end
close cur
deallocate cur