【发布时间】:2021-12-06 13:32:48
【问题描述】:
在调度任务中遇到一些困难。
背景:我有 100 个成员、10 个不同的会议和 10 个不同的活动。 规则:
- 每个成员每项活动只能进行一次。
- 每个活动在每个会话中必须有相同数量的成员。
- 成员必须在每个会话中与(至少大部分)不同的人在一起。
- 每个活动必须在每个会话中运行,每个活动 10 人。
预期的结果是这样的:
| Person ID | Session ID | Activity ID |
|---|---|---|
| 1 | S1 | A |
| 2 | S1 | B |
| 3 | S1 | C |
| 1 | S2 | B |
| 2 | S2 | C |
| 3 | S2 | A |
在上面的示例中,每个会话中的每个活动只有 1 个参与者,我必须将该会话中的该活动锁定为 10 个成员。
我在 excel / SQL 中尝试了几种不同的解决方案,但无法满足所有 3 条规则。最难的是将每个活动/会议时段保持在 10 人以内。
我所拥有的最接近的解决方案如下......虽然它并不漂亮:
SET STATISTICS TIME, io OFF
-- Create list of applicants
IF OBJECT_ID('process.Numbers') IS NOT NULL DROP TABLE process.Numbers
CREATE TABLE Numbers (ApplicantID INT, SessionID INT, GroupID INT)
DECLARE @i INT,
@Session INT,
@Group INT;
SELECT @i = 1;
SET NOCOUNT ON
WHILE @i <= 100
BEGIN
INSERT INTO Numbers (ApplicantID, SessionID) VALUES (@i, 1);
SELECT @i = @i + 1;
END;
-- Duplicate ApplicantID list for each different session
SELECT @Session = 1
WHILE @Session <= 10
BEGIN
IF @Session > 1
BEGIN
INSERT INTO
Numbers (ApplicantID, SessionID)
SELECT ApplicantID, @Session FROM Numbers WHERE SessionID = 1
END
-- SELECT RANDOM TOP 10 AND SET AS GROUP ID
SELECT @Group = 1
WHILE @Group <= 10
BEGIN
WITH dups_check AS ( SELECT ApplicantID,
GroupID,
COUNT(*) AS vol
FROM Numbers
GROUP BY ApplicantID,
GroupID),
cte AS ( SELECT TOP 10 *
FROM Numbers
WHERE numbers.GroupID IS NULL
AND SessionID = @Session
AND NOT EXISTS (SELECT 1
FROM dups_check
WHERE Numbers.ApplicantID = dups_check.ApplicantID
AND dups_check.GroupID = @Group)
ORDER BY newid())
UPDATE cte SET GroupID = @Group
SELECT @Group = @Group + 1
END
SELECT @Session = @Session + 1
END
SELECT * FROM Numbers
SET NOCOUNT OFF
此代码在尝试设置个人已经完成的活动时,会在较高的会话数中开始定期失败。
谢谢!
【问题讨论】:
-
(s1,a1)-> 所有成员,.., (s10,a10)-> 所有成员。
标签: sql excel random sql-server-2012 azure-sql-database