2017-05-16 12 views
5

तो मैं, 2 टेबल देखभाल और ग्राहक है इसएक विशिष्ट अवधि में सभी उपलब्ध आइटम का चयन करें

client { 
    id, 
    name 
} 

caring { 
    id, 
    startDate, 
    endDate, 
    clientId 
} 

जैसे मैं सभी ग्राहकों है कि कम से कम एक दिन के दो प्रदान की तिथियों के बीच उपलब्ध प्राप्त करने की आवश्यकता है, तो आप देख सकते हैं संदर्भ के रूप में मेरा स्क्रीनशॉट।

Screenshot

स्क्रीनशॉट में मैं दो ग्राहकों है, और मुझे उन दोनों को वापस जाने के लिए की जरूरत है। जैसा कि आप देख सकते हैं, पहले क्लाइंट में प्रदान की गई अवधि (16.5.-2 9 .5) के बीच तीन खाली दिन (21.5.-23.5।) हैं और दूसरे क्लाइंट की कोई देखभाल अवधि नहीं है।

इस

SELECT * FROM client cl 
WHERE cl.id NOT IN (SELECT clientId FROM caring 
WHERE endDate >= CURDATE() AND endDate <= DATE_ADD(CURDATE(), INTERVAL 14 DAY)) 

यह एक वापसी केवल ग्राहकों बिल्कुल carings की जरूरत नहीं है कि जैसे अब तक मैं कोशिश की है कुछ। यह आंशिक रूप से मुझे चाहिए क्योंकि यह क्वेरी मेरे स्क्रीनशॉट से पहले क्लाइंट को कवर नहीं करती है। तब मैंने सवाल पूछने की कोशिश की।

SELECT ca.startDate, ca.endDate, cl.firstName, cl.lastName 
FROM caring ca 
LEFT JOIN client cl on cl.id = ca.clientId 
WHERE ca.startDate NOT IN (
    SELECT endDate 
    FROM caring 
) AND ca.startDate <= '2017-05-29' AND ca.endDate >= '2017-05-16' 

लेकिन मुझे वांछित परिणाम नहीं मिल रहे हैं।

कोई विचार यह है कि मैं इसे कैसे प्राप्त कर सकता हूं, अग्रिम में thx!

+1

मेरे पास एक समाधान है (अंतर + समूह/योग द्वारा दिन की गिनती) जो मैं शाम को उत्तर के रूप में पोस्ट करूंगा ... – fheub

+0

समाधान के लिए धन्यवाद ... :) – Jasko

उत्तर

2
इस अवधि के लिए ब्याज और सीमा प्रारंभ/समाप्ति दिनांक की अवधि में

करें carings, क्रमशः। यह सीमा "बुक" की आसान गिनती के लिए अनुमति देगी यानी बाद में मुफ्त दिनों में नहीं।

SELECT ca.id, 
     -- Limit start/end dates to period of interest, respectively 
     GREATEST (ca.startDate, '2017-05-16') AS `effectiveStartDate`, 
     LEAST (ca.endDate, '2017-05-29') AS `effectiveEndDate`, 
     ca.clientId 
    FROM carings ca 
WHERE ca.startDate <= '2017-05-29' AND ca.endDate >= '2017-05-16'; 

इसके बाद, गिनती बुक दिनों:

DATEDIFF (DATE_ADD (LEAST (ca.endDate, '2017-05-29'), INTERVAL 1 DAY), 
      GREATEST (ca.startDate, '2017-05-16')) 
    AS `effectiveDays` 

अंत में, ग्राहकों कि पूरे अवधि में बुक किया जाता है को फ़िल्टर। यह

  • ग्राहक (GROUP BY) प्रति बुक दिनों की राशि
  • को पूरी अवधि (HAVING sumDays < DATEDIFF(...)) के दिनों की संख्या की तुलना द्वारा किया जाता है।

आप भी ग्राहकों है कि पूरे अवधि में बिल्कुल भी बुक नहीं कर रहे हैं चाहते हैं, मैं clients मेज से शुरू करते हैं और "बस" LEFT JOIN (प्रभावी) carings को सुझाव है:

SELECT cl.id, cl.name, IFNULL (SUM (eca.effectiveDays), 0) AS `sumDays` 
    FROM clients cl 
     LEFT JOIN 
     (SELECT ca.id, 
       -- Limit start/end dates to period of interest, respectively 
       GREATEST (ca.startDate, '2017-05-16') AS `effectiveStartDate`, 
       LEAST (ca.endDate, '2017-05-29') AS `effectiveEndDate`, 
       DATEDIFF (
        DATE_ADD (LEAST (ca.endDate, '2017-05-29'), INTERVAL 1 DAY), 
        GREATEST (ca.startDate, '2017-05-16')) 
        AS `effectiveDays`, 
       ca.clientId 
      FROM carings ca 
      WHERE ca.startDate <= '2017-05-29' AND ca.endDate >= '2017-05-16') 
     eca            -- effectiveCarings 
      ON eca.clientId = cl.id 
GROUP BY cl.id, cl.name 
    HAVING sumDays < 
      DATEDIFF (DATE_ADD ('2017-05-29', INTERVAL 1 DAY), '2017-05-16') 
ORDER BY cl.id; 

देखें http://sqlfiddle.com/#!9/1038b9/19

+0

धन्यवाद धन्यवाद ... आपका समाधान वह है जिसे मैं ढूंढता हूं .. :) :) क्वेरी उन सभी ग्राहकों को लौटाती है जिनमें कम से कम एक "सफेद" फ़ील्ड (फ्री डे) है ... :)) – Jasko

1

उन ग्राहकों का चयन करें जिनकी समाप्ति तिथि आपके प्रदत्त अवधि के अंतिम दिन से पहले होती है और निर्दिष्ट अवधि के दौरान एंडडेट और स्टार्टडेट के बीच एक अंतर होता है।

SELECT * FROM client FULL OUTER JOIN caring ON client.id = caring.clientId WHERE endDate <= '2017-05-28' AND DATEDIFF(day, startDate, endDate) > DATEDIFF(day, '2017-05-16' , endDate); 
+1

मुझे यकीन नहीं है अगर मैं क्यू समझता हूं, तो यह कैसे काम करेगा सही ढंग से शेर वह सभी क्लाइंट चाहता है जिनके पास विशिष्ट अवधि –

+1

में कम से कम एक दिन मुफ़्त (कैलेंडर पर सफेद क्षेत्र) है, यह मेरे अंतिम संपादन के बाद ठीक से काम करना चाहिए। –

+0

मदद के लिए धन्यवाद, लेकिन आपका समाधान मेरे मामले के लिए काम नहीं कर रहा है ... :) फेबब से ऊपरी समाधान सही है ... :) – Jasko

संबंधित मुद्दे