Možná něco takového:
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)
To by se mělo pokusit přiřadit zaměstnance náhodně na základě jejich označení a vyřadit stejné aktuální zasílání a domov, a nikoli přiřadit více, než je uvedeno v každém sloupci pro označení. To by však mohlo vrátit stejného zaměstnance na několik míst, protože by se na základě tohoto kritéria mohli shodovat s více než jedním.
UPRAVIT: Poté, co jste viděli váš komentář o tom, že k vyřešení tohoto problému nepotřebujete vysoce výkonný jediný dotaz (což si nejsem jistý, zda je vůbec možné), a protože se zdá, že jde spíše o „jednorázový“ proces, budete Při volání jsem napsal následující kód pomocí kurzoru a jedné dočasné tabulky, abych vyřešil váš problém s přiřazením:
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
Základní myšlenkou je, že iteruje zaměstnance v náhodném pořadí a každému z nich přiřadí náhodné místo, které splňuje kritéria různého domova a aktuálního vysílání, a také kontroluje množství, které bude každému místu přiděleno pro každé označení. abyste zajistili, že umístění nebudou "přeřazena" pro každou roli.
Tento úryvek není ve skutečnosti však změnit svá data. Poslední SELECT
příkaz pouze vrátí navrhovaná přiřazení. Můžete jej však velmi snadno upravit tak, aby prováděl skutečné změny vašeho Employee
podle toho.