【发布时间】:2018-12-27 23:13:57
【问题描述】:
我有两个表:[employee] 和 [task],我想将每个 employee 的 task 表中的 5 个任务分配到跟踪表中。分配需要是随机的,并且每次选择都应该排除那些已经选择的任务。
【问题讨论】:
-
选择查询 in random order 的行。只运行一次查询,并按从上到下的顺序使用该列表。
标签: sql-server
我有两个表:[employee] 和 [task],我想将每个 employee 的 task 表中的 5 个任务分配到跟踪表中。分配需要是随机的,并且每次选择都应该排除那些已经选择的任务。
【问题讨论】:
标签: sql-server
我想我找到了一种优雅的方式来实现你想要的。唯一的问题是,如果您的任务少于 5 x 员工,则某些员工将根本没有分配任何任务。
WITH Employee AS (SELECT ROW_NUMBER() OVER(ORDER BY NewID()) AS ID, * FROM Employee),
Task AS (SELECT ROW_NUMBER() OVER(ORDER BY NewID()) AS ID, * FROM Task)
SELECT *
FROM Employee
LEFT JOIN Task
ON Employee.ID = FLOOR((Task.ID-1)/5)+1
您可以将所需的结果插入到跟踪表中
根据您的评论,添加以确保任务按比例分配,如果任务> 5 x 员工可能会发生问题,系统将分配更多任务给一些员工:
WITH Employee AS (SELECT ROW_NUMBER() OVER(ORDER BY NewID()) AS ID, * FROM Employee),
Task AS (SELECT ROW_NUMBER() OVER(ORDER BY NewID()) AS ID, * FROM Task)
SELECT *
FROM Employee
LEFT JOIN Task
ON Employee.ID = FLOOR((Task.ID-1) %
(SELECT COUNT(*) FROM Employee)
)+1
它使用 Modulus % 运算符来获得整数除法的其余部分,因此它为每个任务提供相关数字,当达到员工总数时,从 1 重新开始。
【讨论】:
在这篇博文中:Return rows in random order 由 Robert Harvey 在评论中链接,您可以找到关于执行涉及ORDER BY NewID() 甚至ORDER BY Rand() 的查询的效率低下的讨论。
根据我的经验,完成您想要做的事情的最佳方法是引入一个新的索引列,比如RandomColumn,用随机数(使用Rand())填充一次,然后每次需要行随机选择一个随机数,比如R,然后选择如下:
...WHERE RandomColumn >= R ORDER BY RandomColumn.
【讨论】: