Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

यादृच्छिक रूप से कार्य स्थान निर्दिष्ट करें और प्रत्येक स्थान निर्दिष्ट कर्मचारियों की संख्या से अधिक नहीं होना चाहिए

शायद कुछ ऐसा:

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 . में वास्तविक परिवर्तन करने के लिए इसे बहुत आसानी से बदल सकते हैं तदनुसार तालिका।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. क्वेरी विश्लेषक में क्वेरी तेजी से चलती है लेकिन C# अनुप्रयोग में धीमी होती है

  2. SQL सर्वर प्रतिकृति को अस्थायी रूप से रोकें

  3. LOG10 () SQL सर्वर में उदाहरण

  4. SQL सर्वर पुन:प्रारंभ करने योग्य अनुक्रमणिका:क्या यह आपके लिए अच्छा है?

  5. कैसे जांचें कि एक स्ट्रिंग एक अद्वितीय पहचानकर्ता है या नहीं?