Mungkin seperti ini:
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)
Itu harus mencoba untuk mencocokkan karyawan secara acak berdasarkan penunjukan mereka membuang saat iniPosting dan rumah yang sama, dan tidak menetapkan lebih dari apa yang ditentukan di setiap kolom untuk penunjukan. Namun, ini dapat mengembalikan karyawan yang sama untuk beberapa tempat, karena mereka dapat mencocokkan lebih dari satu berdasarkan kriteria tersebut.
EDIT: Setelah melihat komentar Anda tentang tidak perlunya kueri tunggal berkinerja tinggi untuk menyelesaikan masalah ini (yang saya tidak yakin bahkan mungkin), dan karena ini tampaknya lebih merupakan proses "satu kali" yang akan Anda lakukan menelepon, saya menulis kode berikut menggunakan kursor dan satu tabel sementara untuk menyelesaikan masalah tugas Anda:
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
Ide dasarnya adalah, bahwa ia mengulangi karyawan, dalam urutan acak, dan memberikan masing-masing Tempat acak yang memenuhi kriteria rumah yang berbeda dan posting saat ini, serta mengendalikan jumlah yang ditugaskan ke setiap tempat untuk setiap Penunjukan untuk memastikan bahwa lokasi tidak "ditugaskan secara berlebihan" untuk setiap peran.
Cuplikan ini tidak sebenarnya mengubah data Anda. SELECT
final terakhir pernyataan hanya mengembalikan tugas yang diusulkan. Namun Anda dapat dengan mudah mengubahnya untuk membuat perubahan aktual pada Employee
Anda tabel yang sesuai.