カーソルが使用されますが、速度が遅く、SQLジョブの大きなボトルネックのように見えます。基本的に、これは、以前に製品IDとアカウントの可視性によってグループ化された特定のソースから上位X個のアクセサリ(販売ランク順に並べられたもの)を除くすべてを削除するためのクリーンアップ作業です。
このコマンドは基本的に、カーソルループの各反復に組み込まれ、exec
手動で編集されます。
このvis
列は、ビットマスクのように機能する複数のテナントを示しています。たとえば、2つのテナントが同じ製品を持っている可能性があります。
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