Måske noget som dette:
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)
Det bør forsøge at matche medarbejdere tilfældigt baseret på deres betegnelse, der kasserer samme aktuelle Posting og hjem, og ikke tildele mere end det, der er angivet i hver kolonne for betegnelsen. Dette kan dog returnere den samme medarbejder flere steder, da de kan matche mere end én ud fra det kriterium.
EDIT: Efter at have set din kommentar om ikke at have et behov for en højtydende enkelt forespørgsel for at løse dette problem (hvilket jeg ikke er sikker på overhovedet er muligt), og da det ser ud til at være mere en "engangs"-proces, vil du blive opkald, skrev jeg følgende kode ved hjælp af en markør og en midlertidig tabel for at løse dit problem med opgaver:
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
Den grundlæggende idé er, at den itererer over medarbejderne, i tilfældig rækkefølge, og tildeler hver enkelt et tilfældigt sted, der opfylder kriterierne for forskellige hjem og aktuelle udstationeringer, samt kontrollerer det beløb, der bliver tildelt hvert sted for hver betegnelse for at sikre, at lokationerne ikke er "overtildelt" for hver rolle.
Dette uddrag ikke faktisk ændre dine data dog. Den endelige SELECT
erklæring returnerer bare de foreslåede opgaver. Du kan dog meget nemt ændre den for at foretage faktiske ændringer af din Employee
tabel i overensstemmelse hermed.