Misschien zoiets als dit:
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)
Dat zou moeten proberen om werknemers willekeurig te matchen op basis van hun aanduiding, waarbij dezelfde huidige Posting en thuis worden weggegooid, en niet meer toewijzen dan wat in elke kolom voor de aanduiding is gespecificeerd. Dit kan echter dezelfde medewerker voor meerdere plaatsen retourneren, omdat ze op basis van die criteria meer dan één kunnen matchen.
BEWERKEN: Na het zien van uw opmerking over het niet nodig hebben van een goed presterende enkele query om dit probleem op te lossen (waarvan ik niet zeker weet of het zelfs mogelijk is), en aangezien het meer een "eenmalig" proces lijkt te zijn dat u zult zijn terwijl ik belde, heb ik de volgende code geschreven met een cursor en een tijdelijke tabel om je probleem met opdrachten op te lossen:
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
Het basisidee is dat het de werknemers herhaalt, in willekeurige volgorde, en aan elk een willekeurige plaats toewijst die voldoet aan de criteria van verschillende thuis- en huidige plaatsingen, en ook het bedrag controleert dat aan elke plaats voor elke aanwijzing wordt toegewezen om ervoor te zorgen dat de locaties niet "over-toegewezen" worden voor elke rol.
Dit fragment niet daadwerkelijk uw gegevens wijzigen. De laatste SELECT
statement retourneert alleen de voorgestelde toewijzingen. U kunt het echter heel gemakkelijk wijzigen om daadwerkelijke wijzigingen aan te brengen in uw Employee
tabel dienovereenkomstig.