मैं एक और दृष्टिकोण के साथ अपनी टोपी रिंग में फेंकने जा रहा हूं:
संपादित करें: मुझे कुछ देर से एहसास हुआ कि प्रश्न में Oracle फ़ंक्शन दूसरे तर्क के रूप में एक स्ट्रिंग लेता है, और इसलिए यह आवश्यकता के अनुरूप नहीं है। हालाँकि MySQL ने पहले से ही 0 - 6 को सोमवार - रविवार के रूप में परिभाषित कर दिया है, और वैसे भी मुझे इस प्रकार की चीज़ के लिए एक तर्क के रूप में एक स्ट्रिंग का उपयोग करने के लिए नैतिक आपत्ति है। एक स्ट्रिंग या तो उपयोगकर्ता इनपुट से आएगी या संख्यात्मक और स्ट्रिंग मानों के बीच उच्च स्तरीय कोड में एक और मैपिंग। एक पूर्णांक क्यों नहीं पारित करें? :)पी>
CREATE FUNCTION `fnDayOfWeekGetNext`(
p_date DATE,
p_weekday TINYINT(3)
) RETURNS date
BEGIN
RETURN DATE_ADD(p_date, INTERVAL p_weekday - WEEKDAY(p_date) + (ROUND(WEEKDAY(p_date) / (p_weekday + WEEKDAY(p_date) + 1)) * 7) DAY);
END
उस हिस्से को तोड़ने के लिए जो INTERVAL
. निर्धारित करता है मूल्य:
समीकरण के पहले भाग को निर्दिष्ट कार्यदिवस और निर्दिष्ट तिथि के कार्यदिवस के बीच ऑफसेट प्राप्त होता है:
p_weekday - WEEKDAY(p_date)
यह एक सकारात्मक संख्या लौटाएगा यदि p_weekday
WEEKDAY(p_date)
. से बड़ा है और इसके विपरीत। यदि वे समान हैं तो शून्य वापस कर दिया जाएगा।
ROUND()
खंड का उपयोग यह निर्धारित करने के लिए किया जाता है कि सप्ताह का अनुरोधित दिन (p_weekday
.) ) वर्तमान सप्ताह में दिनांक के सापेक्ष पहले ही हो चुका है (p_date
) निर्दिष्ट। तो, उदाहरण के तौर पर...
ROUND(WEEKDAY('2019-01-25') / (6 + WEEKDAY('2019-01-25') + 1))
..रिटर्न 0
, यह दर्शाता है कि रविवार (6
) इस सप्ताह नहीं हुआ है, क्योंकि 2019-01-25
शुक्रवार है। इसी तरह...
ROUND(WEEKDAY('2019-01-25') / (2 + WEEKDAY('2019-01-25') + 1))
...रिटर्न 1
क्योंकि बुधवार (2
) पहले ही बीत चुका है। ध्यान दें कि यह 0
return लौटाएगा अगर p_weekday
p_date
. के कार्यदिवस के समान है ।
यह मान (या तो 1
या 0
) को तब स्थिर 7
. से गुणा किया जाता है (सप्ताह में दिनों की संख्या)।
इसलिए यदि p_weekday
चालू सप्ताह में पहले ही हो चुका है, यह ऑफ़सेट में 7 जोड़ देगा p_weekday - WEEKDAY(p_date)
, क्योंकि वह ऑफ़सेट एक ऋणात्मक संख्या होगी और हम भविष्य में एक तिथि चाहते हैं।
अगर p_weekday
चालू सप्ताह में अभी तक नहीं हुआ है, तो हम ऑफ़सेट को वर्तमान तिथि में जोड़ सकते हैं क्योंकि ऑफ़सेट एक सकारात्मक संख्या होगी। इसलिए खंड ROUND(...) * 7
शून्य के बराबर है और, संक्षेप में, अनदेखा किया गया है।
इस दृष्टिकोण के लिए मेरी इच्छा एक IF()
. का अनुकरण करना था गणितीय रूप से स्थिति। यह समान रूप से मान्य होगा:
RETURN DATE_ADD(p_date, INTERVAL p_weekday - WEEKDAY(p_date) + IF(p_weekday - WEEKDAY(p_date) < 0, 7, 0) DAY);
और निष्पक्षता के हित में, 1M पुनरावृत्तियों को प्रत्येक फ़ंक्शन के कुछ बार चलाने में IF
-आधारित संस्करण का औसत ROUND
. से लगभग 4.2% तेज है -आधारित संस्करण।