SQL - 将工作分配给工人 - 循环的替代方案?
SQL - Assign jobs to workers - Alternative to a loop?
在 SQL Server 2019 中,我有一个 table 未分配的任务,还有另一个 table 可以处理这些任务的工作人员。我的要求是通过将 Tasks
table 中的 WorkerID
列更新为将执行任务的工人的 ID
来平均分配工人在可用任务上。
- 每次 SQL 为 运行 时,工人数量和任务数量都可能不同。
- 其中一个 table 的记录可能比另一个多。
- 任务分配从 Workers table 中的第一个 worker 开始,并在所有任务分配完毕后结束。 (出于 运行 运行 的公平目的,没有对工人进行随机化。)
- table 可以有零条记录。
给定具有以下结构的 tables,我想知道如何在不使用循环的情况下进行这些赋值。我怀疑这可以通过使用行号、等级或其他类似 SQL 服务器魔法来完成,但我一直无法弄清楚。谢谢!
任务 table:
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
工人 table:
WorkerID WorkerName
---------------------
67 Larry
42 Sue
10 Peter
45 Steve
Tasks
table 的预期结果:
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
您可以使用 window 函数分配一个数字,然后 join
。一个“round-robin”方法是:
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;
在 SQL Server 2019 中,我有一个 table 未分配的任务,还有另一个 table 可以处理这些任务的工作人员。我的要求是通过将 Tasks
table 中的 WorkerID
列更新为将执行任务的工人的 ID
来平均分配工人在可用任务上。
- 每次 SQL 为 运行 时,工人数量和任务数量都可能不同。
- 其中一个 table 的记录可能比另一个多。
- 任务分配从 Workers table 中的第一个 worker 开始,并在所有任务分配完毕后结束。 (出于 运行 运行 的公平目的,没有对工人进行随机化。)
- table 可以有零条记录。
给定具有以下结构的 tables,我想知道如何在不使用循环的情况下进行这些赋值。我怀疑这可以通过使用行号、等级或其他类似 SQL 服务器魔法来完成,但我一直无法弄清楚。谢谢!
任务 table:
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
工人 table:
WorkerID WorkerName
---------------------
67 Larry
42 Sue
10 Peter
45 Steve
Tasks
table 的预期结果:
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
您可以使用 window 函数分配一个数字,然后 join
。一个“round-robin”方法是:
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;