在 SQL Server 中,我有一个 id 的源列表,我想以特定的方式重新排序以进行处理。我的原始表有一个 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,然后在第二个周期中为 10、20、50。如果桶是 4,那么第一个是 10,20,40,50,第二个是 10,20,40,50。
我表达问题的另一种方式是我想通过计数从新表中获取第一个 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