शायद कुछ ऐसा:
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)
यह कर्मचारियों को उनके पदनाम के आधार पर यादृच्छिक रूप से मिलान करने का प्रयास करना चाहिए, समान वर्तमान पोस्टिंग और घर को छोड़कर, और पदनाम के लिए प्रत्येक कॉलम में निर्दिष्ट से अधिक असाइन नहीं करना चाहिए। हालांकि, यह एक ही कर्मचारी को कई स्थानों पर लौटा सकता है, क्योंकि वे उस मानदंड के आधार पर एक से अधिक का मिलान कर सकते हैं।
संपादित करें: इस समस्या को हल करने के लिए उच्च प्रदर्शन करने वाली एकल क्वेरी की आवश्यकता नहीं होने के बारे में आपकी टिप्पणी देखने के बाद (जो मुझे यकीन नहीं है कि यह भी संभव है), और चूंकि यह एक "वन-ऑफ" प्रक्रिया से अधिक प्रतीत होता है कि आप होंगे कॉलिंग, मैंने आपकी असाइनमेंट की समस्या को हल करने के लिए एक कर्सर और एक अस्थायी तालिका का उपयोग करके निम्नलिखित कोड लिखा है:
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
मूल विचार यह है कि यह कर्मचारियों पर यादृच्छिक क्रम में पुनरावृति करता है, और प्रत्येक को एक यादृच्छिक स्थान प्रदान करता है जो अलग-अलग घर और वर्तमान पोस्टिंग के मानदंडों को पूरा करता है, साथ ही प्रत्येक पद के लिए प्रत्येक स्थान को आवंटित राशि को नियंत्रित करता है। यह सुनिश्चित करने के लिए कि प्रत्येक भूमिका के लिए स्थान "ओवर-असाइन्ड" नहीं हैं।
यह स्निपेट नहीं हालांकि वास्तव में अपना डेटा बदलें। अंतिम SELECT
कथन केवल प्रस्तावित कार्य लौटाता है। हालांकि आप अपने Employee
. में वास्तविक परिवर्तन करने के लिए इसे बहुत आसानी से बदल सकते हैं तदनुसार तालिका।