Vielleicht so etwas:
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)
Das sollte versuchen, Mitarbeiter zufällig auf der Grundlage ihrer Bezeichnung abzugleichen, wobei dieselbe aktuelle Posting und Heimat verworfen wird, und nicht mehr als das zuzuweisen, was in jeder Spalte für die Bezeichnung angegeben ist. Dies könnte jedoch denselben Mitarbeiter für mehrere Plätze zurückgeben, da er basierend auf diesen Kriterien mehr als einem entsprechen könnte.
BEARBEITEN: Nachdem Sie Ihren Kommentar gesehen haben, dass Sie keine leistungsstarke einzelne Abfrage benötigen, um dieses Problem zu lösen (was meiner Meinung nach überhaupt nicht möglich ist), und da es eher ein "einmaliger" Prozess zu sein scheint, der Sie sein werden Als ich angerufen habe, habe ich den folgenden Code mit einem Cursor und einer temporären Tabelle geschrieben, um Ihr Problem der Zuweisungen zu lösen:
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
Die Grundidee ist, dass es in zufälliger Reihenfolge über die Mitarbeiter iteriert und jedem einen zufälligen Ort zuweist, der die Kriterien unterschiedlicher Wohnorte und aktueller Posten erfüllt, sowie die Menge steuert, die jedem Ort für jede Bezeichnung zugewiesen wird um sicherzustellen, dass die Standorte nicht für jede Rolle "überbelegt" werden.
Dieses Snippet nicht ändern Sie Ihre Daten jedoch tatsächlich. Das letzte SELECT
-Anweisung gibt nur die vorgeschlagenen Zuweisungen zurück. Sie können es jedoch sehr einfach ändern, um tatsächliche Änderungen an Ihrem Employee
vorzunehmen Tabelle entsprechend.