【问题标题】:Create equal sized, random buckets, with no repetition to the row创建大小相等的随机存储桶,行不重复
【发布时间】:2021-12-06 13:32:48
【问题描述】:

在调度任务中遇到一些困难。

背景:我有 100 个成员、10 个不同的会议和 10 个不同的活动。 规则:

  1. 每个成员每项活动只能进行一次。
  2. 每个活动在每个会话中必须有相同数量的成员。
  3. 成员必须在每个会话中与(至少大部分)不同的人在一起。
  4. 每个活动必须在每个会话中运行,每个活动 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


【解决方案1】:

我尝试使用您的代码生成申请人ID 和会话ID 行并修改最后一部分以使用排名函数生成GroupID 列。

以下是我尝试过的结果:

SET STATISTICS TIME, io OFF

-- Create list of applicants
IF OBJECT_ID('dbo.Numbers') IS NOT NULL DROP TABLE dbo.Numbers

CREATE TABLE dbo.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 @Session = @Session + 1
END

SET NOCOUNT OFF

drop table if exists #temp;

select ApplicantID, SessionID, row_number() OVER(PARTITION BY applicantID ORDER BY applicantID) AS grp_row into #temp
from Numbers

update a
set a.GroupID = b.grp_row
from Numbers a
join #temp b on a.ApplicantID = b. ApplicantID and a.SessionID = b.SessionID
where a.GroupID is null
  1. 每个成员每项活动只能进行一次。

有 100 个申请者,例如,我展示申请者 1 和 100。这里每个申请者每个 groupID 只有一次。

  1. 每个活动在每个会话中必须有相同数量的成员。

有 10 个 GroupID,每个 GroupID 的申请人数相同 (100)。

  1. 成员必须在每个会话中与(至少大部分)不同的人在一起。

有 100 名申请者,但我以前 10 名为例。这里每个 sessionID 都有不同的申请者。

【讨论】:

  • 感谢您的回复。不幸的是,这使 50 人一起参加了一项活动。我必须将每次活动的人数控制在 10 人以内。每个活动都必须一直在运行。我已经编辑了我的原始帖子,将其添加为规则,以便于可见性。
猜你喜欢
  • 2012-06-08
  • 1970-01-01
  • 2017-12-22
  • 1970-01-01
  • 1970-01-01
  • 2011-09-23
  • 1970-01-01
  • 2018-02-15
  • 1970-01-01
相关资源
最近更新 更多