Có thể như thế này:
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)
Điều đó sẽ cố gắng so khớp các nhân viên một cách ngẫu nhiên dựa trên chỉ định của họ, loại bỏ cùng hiện tại và nhà riêng, và không chỉ định nhiều hơn những gì được chỉ định trong mỗi cột cho chỉ định. Tuy nhiên, điều này có thể trả lại cùng một nhân viên cho một số nơi vì họ có thể khớp với nhiều nhân viên dựa trên tiêu chí đó.
CHỈNH SỬA: Sau khi xem nhận xét của bạn về việc không cần một truy vấn đơn lẻ có hiệu suất cao để giải quyết vấn đề này (điều mà tôi không chắc là có thể thực hiện được) và vì nó dường như là quá trình "một lần" mà bạn sẽ đang gọi, tôi đã viết mã sau bằng con trỏ và một bảng tạm thời để giải quyết vấn đề bài tập của bạn:
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
Ý tưởng cơ bản là nó lặp lại các nhân viên, theo thứ tự ngẫu nhiên và chỉ định cho mỗi người một Địa điểm ngẫu nhiên đáp ứng các tiêu chí về đăng bài tại nhà và hiện tại khác nhau, cũng như kiểm soát số tiền được chỉ định cho từng vị trí cho mỗi Chỉ định để đảm bảo rằng các vị trí không bị "chỉ định quá mức" cho từng vai trò.
Đoạn mã này không thực sự thay đổi dữ liệu của bạn. SELECT
cuối cùng câu lệnh chỉ trả về các nhiệm vụ được đề xuất. Tuy nhiên, bạn rất có thể dễ dàng thay đổi nó để thực hiện các thay đổi thực sự đối với Employee
của mình bảng tương ứng.