तीन शिफ्ट में ड्यूटी देने की कोशिश कर रहा हूं

निम्नलिखित बाधा है:

1st shift will have 5 employee 
>2nd shift will have 3 employee
3rd shift will have 2 employee 

यदि किसी व्यक्ति को किसी भी पाली में ड्यूटी आवंटित की जाती है तो उसे दो पाली में ड्यूटी की अनुमति नहीं दी जाएगी। भूतपूर्व। यदि मिस्टर एक्स को 3 अगस्त को दूसरी पाली में ड्यूटी आवंटित की जाती है तो उन्हें न तो 3 अगस्त को तीसरी पाली में और न ही 4 अगस्त को पहली पाली में ड्यूटी मिलेगी

मैंने कर्मचारी को बेतरतीब ढंग से चुनने के लिए rand() फ़ंक्शन का उपयोग किया है। मुझे बाधा 4 की समस्या का सामना करना पड़ रहा है। यानी मैं यह कैसे सुनिश्चित कर सकता हूं कि जिस कर्मचारी को पहली पाली में ड्यूटी आवंटित की गई है, उसे दूसरी या तीसरी पाली में आवंटित नहीं किया जाएगा।

मेरी MySQL क्वेरी है:

SELECT * FROM `employee` ORDER BY rand()
-1
Ranjit Kumar 11 अगस्त 2018, 11:20
Php में प्रयास करें और हमारे साथ साझा करें
 – 
Niklesh Raut
11 अगस्त 2018, 11:28
देखें सरल-एसक्यूएल-क्वेरी" शीर्षक = "मुझे एक बहुत ही सरल एसक्यूएल क्वेरी के लिए एक एमसीवी क्यों प्रदान करना चाहिए">meta.stackoverflow.com/questions/333952/…
 – 
Strawberry
11 अगस्त 2018, 12:10
आप शिफ्ट असाइनमेंट विवरण कैसे संग्रहीत कर रहे हैं?
 – 
Sheikh Azad
11 अगस्त 2018, 12:41

2 जवाब

मुझे लगता है कि एसक्यूएल में हल करना एक मुश्किल समस्या है, लेकिन अगर मैं इसे करने का प्रयास कर रहा था, तो शायद मैं कर्मचारियों को यादृच्छिक बनाने के साथ शुरू करूंगा ...

DROP TABLE IF EXISTS employees;

CREATE TABLE employees 
(employee_id SERIAL PRIMARY KEY);

INSERT INTO employees VALUES
(101),(102),(103),(104),(105),(106),(107),(108),(109),(110);

SELECT employee_id,@i:=@i+1 i FROM (SELECT employee_id FROM employees ORDER BY RAND()) x,(SELECT @i:=0) vars;
+-------------+------+
| employee_id | i    |
+-------------+------+
|         108 |    1 |
|         109 |    2 |
|         110 |    3 |
|         103 |    4 |
|         105 |    5 |
|         106 |    6 |
|         102 |    7 |
|         104 |    8 |
|         107 |    9 |
|         101 |   10 |
+-------------+------+

अब, जब तक हमारे पास कम से कम 3 दिनों के लायक कर्मचारी हैं (5+3+2=10), हम केवल सूची के माध्यम से साइकिल चला सकते हैं, और जान सकते हैं कि प्रत्येक कर्मचारी के पास प्रत्येक काम के बीच कम से कम दो लगातार आराम दिन होंगे। दिन।

यहाँ समस्या के दूसरे पहलू के बारे में एक विचार है...

DROP TABLE IF EXISTS shifts;

CREATE TABLE shifts 
(shift_id SERIAL PRIMARY KEY
,shift_size INT NOT NULL
);

INSERT INTO shifts VALUES
(1,5),(2,3),(3,2),(4,3),(5,2);

SELECT shift_id
     , ROUND(COALESCE(@j:=@prev+1,1),0) range_start
     , range_end, @prev:=range_end 
  FROM 
     ( SELECT x.*
            , SUM(y.shift_size) range_end 
         FROM shifts x 
         JOIN shifts y 
           ON y.shift_id <= x.shift_id 
        GROUP 
           BY x.shift_id
     ) b
     , ( SELECT @j:=1,@prev:=null) vars
 ORDER 
    BY shift_id;
+----------+-------------+-----------+------------------+
| shift_id | range_start | range_end | @prev:=range_end |
+----------+-------------+-----------+------------------+
|        1 |           1 |         5 |                5 |
|        2 |           6 |         8 |                8 |
|        3 |           9 |        10 |               10 |
|        4 |          11 |        13 |               13 |
|        5 |          14 |        15 |               15 |
+----------+-------------+-----------+------------------+

तो अब आपके पास एक कर्मचारी अनुक्रम आईडी और एक सीमा है जिसके भीतर वे आईडी गिर सकते हैं। सीमा कर्मचारियों की सूची से बड़ी है, इसलिए आपको कर्मचारियों की तालिका के आकार को श्रेणी के मापांक के रूप में उपयोग करना होगा।

 SELECT a.shift_id
      , MOD(a.range_start-1,(SELECT COUNT(*) FROM employees))+1 range_start
      , MOD(a.range_end-1,(SELECT COUNT(*) FROM employees))+1 range_end
   FROM
      ( SELECT shift_id
      , ROUND(COALESCE(@j:=@prev+1,1),0) range_start
      , range_end, @prev:=range_end
   FROM
      ( SELECT x.*
             , SUM(y.shift_size) range_end
          FROM shifts x
          JOIN shifts y
            ON y.shift_id <= x.shift_id
         GROUP
            BY x.shift_id
      ) b
      , ( SELECT @j:=1,@prev:=null) vars
  ORDER
     BY shift_id
     ) a
   ORDER BY shift_id;
+----------+-------------+-----------+
| shift_id | range_start | range_end |
+----------+-------------+-----------+
|        1 |           1 |         5 |
|        2 |           6 |         8 |
|        3 |           9 |        10 |
|        4 |           1 |         3 |
|        5 |           4 |         5 |
+----------+-------------+-----------+

मुझे लगता है कि मैं पाठक के लिए एक अभ्यास के रूप में अंतिम चरण छोड़ सकता हूं।

0
Strawberry 12 अगस्त 2018, 08:55

चूंकि आपने अधिक विवरण प्रदान नहीं किया है, इसलिए यह पता लगाना कठिन है कि आप डेटाबेस में जानकारी कैसे संग्रहीत कर रहे हैं। मुझे लगता है कि निम्नलिखित प्रश्न आपके मामले के अनुरूप होंगे:

SELECT * FROM employee e
WHERE e.employee_id NOT IN (
                            SELECT es.employee_id FROM emp_shifts es
                            WHERE shift IN (...)
                            )
ORDER BY RAND()

मुझे लगता है कि आप शिफ्ट आवंटन को emp_shifts तालिका में संग्रहीत कर रहे हैं। ... अंतिम 2 शिफ्ट हैं जिन्हें आप बाहर करना चाहते हैं।

-1
Sheikh Azad 11 अगस्त 2018, 14:03
कृपया एक sqlfiddle प्रदान करें ताकि मैं एक बेहतर समाधान प्रदान कर सकूं।
 – 
Sheikh Azad
11 अगस्त 2018, 14:03