2012-03-16 19 views
5

में निकटतम कार्य दिवस की गणना करें मुझे ऑर्डर के लिए अनुरोधित डिलीवरी तिथि के आधार पर पोस्टग्रेस क्वेरी में कुछ आइटम शेड्यूल करने की आवश्यकता है। तो उदाहरण के लिए, आदेश सोमवार (उदाहरण के लिए 2012031 9) पर अनुरोधित डिलीवरी है, और आदेश को पहले कार्य दिवस (20120316) पर तैयार करने की आवश्यकता है।पोस्टग्रेज़

सबसे प्रत्यक्ष विधि पर विचार? मैं एक दिनांक तालिका जोड़ने के लिए खुला हूँ। मैं सोच रहा हूं कि केस स्टेटमेंट्स के लंबे सेट से बेहतर तरीका होना चाहिए: एक्सट्रैक्ट चुनें (टाइमस्टैम्प से 2001-02-16 20:38:40 ');

उत्तर

7

पिछले काम दिन है करने के लिए:

select max(s.a) as work_day 
from (
    select s.a::date 
    from generate_series('2012-01-02'::date, '2050-12-31', '1 day') s(a) 
    where extract(dow from s.a) between 1 and 5 
    except 
    select holiday_date 
    from holiday_table 
    ) s 
where s.a < '2012-03-19' 
; 

आप अगला कार्य दिवस बस क्वेरी को उलटने चाहते हैं।

+0

क्या होगा अगर शुक्रवार छुट्टी हो? –

+1

एक आकर्षण की तरह काम किया। धन्यवाद। दूसरों के लिए एक चीज़ को स्पष्ट करने के लिए, जब क्लोडोल्डो कहते हैं, "क्वेरी को उलटा करें" तो इसे "मिन (एसए) का चयन करें", < to > को परिवर्तित न करें। – Dustin

+0

छुट्टियां मैं थोड़ा अलग तरीके से संभालने जा रहा हूं। मैं ऊपर अपने समाधान का उपयोग करने के लिए मानता हूं कि आपको उन्हें कहीं स्टोर करना होगा। लेकिन वे हमारे लिए पर्याप्त कम हैं कि हम आदेशों को फिर से निर्धारित करेंगे। – Dustin

0
CREATE TABLE Holidays (Holiday, PrecedingBusinessDay) AS VALUES 
    ('2012-12-25'::DATE, '2012-12-24'::DATE), 
    ('2012-12-26'::DATE, '2012-12-24'::DATE); 
SELECT Day, COALESCE(PrecedingBusinessDay, PrecedingMondayToFriday) 
FROM 
    (SELECT Day, Day - CASE DATE_PART('DOW', Day) 
         WHEN 0 THEN 2 
         WHEN 1 THEN 3 
         ELSE 1 
        END AS PrecedingMondayToFriday 
    FROM TestDays) AS PrecedingMondaysToFridays 
LEFT JOIN Holidays ON PrecedingMondayToFriday = Holiday; 

आप कुछ पहचानकर्ताओं का नाम बदलना चाहेंगे :-)।

4
SELECT y.d AS prep_day 
FROM (
    SELECT generate_series(dday - 8, dday - 1, interval '1d')::date AS d 
    FROM (SELECT '2012-03-19'::date AS dday) x 
    ) y 
LEFT JOIN holiday h USING (d) 
WHERE h.d IS NULL 
AND extract(isodow from y.d) < 6 
ORDER BY y.d DESC 
LIMIT 1; 
  • यह तेजी केवल के रूप में कई दिनों उत्पन्न करने के लिए आवश्यक के रूप में होना चाहिए। मैं डिलीवरी से एक सप्ताह पहले उत्पन्न करता हूं। इसमें सभी संभावनाएं शामिल होनी चाहिए।

  • isodow as extract parameter कार्यदिवसों के परीक्षण के लिए dow से अधिक सुविधाजनक है।

  • min()/max(), ORDER BY/LIMIT 1, यह मेरी क्वेरी में कुछ पंक्तियों के साथ स्वाद का विषय है।

  • अवरोही क्रम में कई उम्मीदवार दिन प्राप्त करने के लिए, केवल शीर्ष पिक नहीं, LIMIT 1 बदलें।

  • मैंने एक सबक्वायरी में dday (डिलीवरी दिन) रखा है ताकि आपको केवल इसे एक बार इनपुट करना होगा। आप date या timestamp शाब्दिक दर्ज कर सकते हैं। इसे किसी भी तरह से date पर डाला गया है।

4

यह आपको पिछले व्यावसायिक दिन देता है।

SELECT 
    CASE (EXTRACT(ISODOW FROM current_date)::integer) % 7 
     WHEN 1 THEN current_date-3 
     WHEN 0 THEN current_date-2 
     ELSE current_date-1 
    END AS previous_business_day 
संबंधित मुद्दे