随机分配工作地点,每个地点不应超过指定员工的数量

Kum*_*rav 8 sql t-sql sql-server sql-server-2005 sql-server-2008

我试图在一个地方列表中选择员工的独特随机发布/招聘地点,所有员工已经在这些地方张贴,我正在尝试为他们生成一个新的随机发布地点,其中"where"条件为"员工新随机位置将不等于其所在地并随机选择具有其名称的员工必须小于或等于"地方"表中的"地方明智"指定号码"

Employee表是:

EmpNo   EmpName           CurrentPosting    Home        Designation   RandomPosting
1       Mac               Alabama           Missouri      Manager       
2       Peter             California        Montana       Manager       
3       Prasad            Delaware          Nebraska      PO       
4       Kumar             Indiana           Nevada        PO       
5       Roy               Iowa              New Jersey    Clerk       
Run Code Online (Sandbox Code Playgroud)

等等...

而Places表(PlaceNames与员工人数 - 指定明智)是: -

PlaceID  PlaceName      Manager     PO    Clerk
1        Alabama           2        0     1
2        Alaska            1        1     1
3        Arizona           1        0     2
4        Arkansas          2        1     1
5        California        1        1     1
6        Colorado          1        1     2
7        Connecticut       0        2     0
Run Code Online (Sandbox Code Playgroud)

等等...

尝试使用newid(),如下所示,并能够选择具有RandomPosting地名的员工,

WITH cteCrossJoin AS (
SELECT e.*, p.PlaceName AS RandomPosting,
       ROW_NUMBER() OVER(PARTITION BY e.EmpNo ORDER BY NEWID()) AS RowNum
    FROM Employee e
        CROSS JOIN  Place p
    WHERE e.Home <> p.PlaceName
)
SELECT *
FROM cteCrossJoin
WHERE RowNum = 1;
Run Code Online (Sandbox Code Playgroud)

另外我需要根据指定号码限制随机选择(在Places表格中)......即为每个员工随机分配一个PlaceName(来自Places),这不等于CurrentPosting和Home(在Employee中)和Place wise指定不超过给定的数字.

提前致谢.

Pab*_*meo 1

也许是这样的:

select C.* from 
(
    select *, ROW_NUMBER() OVER(PARTITION BY P.PlaceID, E.Designation ORDER BY NEWID()) AS RandPosition
        from Place as P cross join Employee E
    where P.PlaceName != E.Home AND P.PlaceName != E.CurrentPosting
) as C
where 
    (C.Designation = 'Manager' AND C.RandPosition <= C.Manager) OR
    (C.Designation = 'PO' AND C.RandPosition <= C.PO) OR
    (C.Designation = 'Clerk' AND C.RandPosition <= C.Clerk)
Run Code Online (Sandbox Code Playgroud)

这应该尝试根据员工的指定随机匹配员工,丢弃相同的 currentPosting 和 home,并且分配的内容不得超过指定每列中指定的内容。但是,这可能会将同一名员工返回多个位置,因为他们可以根据该标准匹配多个位置。


编辑: 在看到您关于不需要高性能单个查询来解决这个问题(我不确定是否可能)的评论后,并且因为它似乎更像是一个“一次性”过程,您将调用时,我使用游标和一个临时表编写了以下代码来解决您的分配问题:

select *, null NewPlaceID into #Employee from Employee

declare @empNo int
DECLARE emp_cursor CURSOR FOR  
SELECT EmpNo from Employee order by newid()

OPEN emp_cursor   
FETCH NEXT FROM emp_cursor INTO @empNo

WHILE @@FETCH_STATUS = 0   
BEGIN
    update #Employee 
    set NewPlaceID = 
        (
        select top 1 p.PlaceID from Place p 
        where 
            p.PlaceName != #Employee.Home AND 
            p.PlaceName != #Employee.CurrentPosting AND
            (
                CASE #Employee.Designation 
                WHEN 'Manager' THEN p.Manager
                WHEN 'PO' THEN p.PO
                WHEN 'Clerk' THEN p.Clerk
                END
            ) > (select count(*) from #Employee e2 where e2.NewPlaceID = p.PlaceID AND e2.Designation = #Employee.Designation)
        order by newid()
        ) 
    where #Employee.EmpNo = @empNo
    FETCH NEXT FROM emp_cursor INTO @empNo   
END

CLOSE emp_cursor
DEALLOCATE emp_cursor

select e.*, p.PlaceName as RandomPosting from Employee e
inner join #Employee e2 on (e.EmpNo = e2.EmpNo)
inner join Place p on (e2.NewPlaceID = p.PlaceID)

drop table #Employee
Run Code Online (Sandbox Code Playgroud)

基本思想是,它以随机顺序迭代员工,并为每个人分配一个满足不同家庭和当前职位标准的随机位置,并控制为每个指定分配给每个位置的数量确保每个角色的位置不会“过度分配”。

不过,这个片段实际上并没有改变您的数据。最终SELECT语句仅返回建议的作业。但是,您可以很容易地更改它,以相应地对表进行实际更改Employee