SQL-将作业分配给工人-循环的替代方法?

问题描述

sql Server 2019中,我有一个未分配任务表,以及另一个可用于处理这些任务的工作器表。我的要求是,用要执行任务的工作人员的WorkerID更新Tasks表中的ID列,以在可用任务上平均分配工作人员。

  • 每次运行sql时,工作程序的数目和任务的数目都可以不同。
  • 任何一个表都可能比另一个表具有更多的记录。
  • 任务分配仅从“工作者”表中的第一个工作者开始,并在任务全部分配后结束。 (为了公平起见,没有对工人进行随机分配。)
  • 每个表都可以有零个记录。

给出具有以下结构的表,我想知道如何在不使用循环的情况下进行这些分配。我怀疑可以通过使用行号,行号或其他类似的sql Server魔术来做到这一点,但我一直无法弄清楚。谢谢!

任务表:

JobID    JobName           WorkerID
------------------------------------
23       Carry Groceries   NULL
1234     Drive             NULL
6543     Dig               NULL
234567   Walk              NULL
78       Clean Room        NULL
54       Cook Dinner       NULL
2        Move Logs         NULL
34       Cut Grass         NULL
99       Milk Chickens     NULL

工人表:

WorkerID   WorkerName
---------------------
67         Larry
42         Sue
10         Peter
45         Steve

Tasks表的预期结果:

JobID    JobName           WorkerID
--------------------------------------
23       Carry Groceries   67
1234     Drive             42
6543     Dig               10
234567   Walk              45
78       Clean Room        67
54       Cook Dinner       42
2        Move Logs         10
34       Cut Grass         45
99       Milk Chickens     67

解决方法

您可以使用窗口功能,然后按join来分配数字。一种“循环”方法是:

with toupdate as (
      select t.*,row_number() over (order by (select null)) as seqnum
      from tasks t
     )
update toupdate
     from toupdate join
          (select w.*,row_number() over (order by (select null)) as seqnum,count(*) over () as cnt
           from workers w
          ) w
          on w.seqnum = ( (toupdate.seqnum - 1) % w.cnt) + 1;