SQL Server には、処理のために特定の方法で並べ替えたい ID のソース リストがあります。元のテーブルには、10,10,10,10,10,20,20,20,20,30,40,40,50,50,60 のような ID のリストと、それぞれに関連付けられた一意のキーがあります。それらは任意の順序にすることができます。競合しないように、ウィンドウまたはサイクルごとにバケットに配布したいと考えています。私は集計関数に精通していますが、分散させるための数学に問題があります。ループで実行することもできますが、パフォーマンス上の理由から、可能であれば単一のクエリで実行したいと考えています。
次のようなカウントと優先度を取得するクエリがあります
Count Id Priority
5 10 1
4 20 2
2 40 3
2 50 4
1 30 5
1 60 6
バケットの数は任意ですが、事前に決定されます。3 の場合、最初のサイクルで id の 10,20,40 が必要で、2 番目のサイクルで 10,20,50 が必要です。バケットが 4 の場合、最初は 10,20,40,50、2 番目は 10,20,40,50 です。
問題を表現するもう 1 つの方法は、新しいテーブルから最初の x をカウントで取得し、カウントを減らしてから、使い果たされるまで次の x を取得することです。
提案された解決策を取り、書き直しましたが、可能であれば、単一のSQLクエリ解決策を探しています。
提案されたループを少し更新しましたが、これはもう少し最適化する必要がありますが、まだ実際のワークロードに更新していません
declare @bucket int, @b int, @maxrows int
declare @buckets table (fstrEntityHash varchar(100), bucket int)
declare @count table (flngCount int, fstrEntityHash varchar(100))
declare @bucketTemp table (fstrEntityHash varchar(100), bucket int)
select @bucket = 3, @maxrows = 20
insert into @count
select COUNT(1) as flngCount,
fstrEntityHash
from tblTest
group by fstrEntityHash
order by COUNT(1) desc
set @b = 1
while (1 = 1)
begin
insert into @bucketTemp
select top (@bucket) fstrEntityHash, @b
from @count
where flngCount > 0
order by flngCount desc;
if @@rowcount = 0
break
update C
set C.flngCount -= 1
from @count C, @bucketTemp I
where C.fstrEntityHash = I.fstrEntityHash
insert into @buckets
select *
from @bucketTemp
if (select count(1) from @buckets) >= @maxrows
break
select @b = @b + 1
delete from @bucketTemp
end
select * from @buckets