2012-03-29 14 views
9

का उपयोग कर मौजूदा बिजनेस डे के साथ एक सप्ताह में पिछले कारोबारी दिन कैसे प्राप्त करें मेरे पास एक एसएसआईएस पैकेज है जो व्यावसायिक दिनों (सोम-शुक्र) पर चलता है। अगर मुझे ट्यूज़डे, पृष्ठभूमि (डीबी) पर फ़ाइल प्राप्त होती है, तो यह पिछले कारोबारी दिन की तारीख लेता है और कुछ लेनदेन करता है। अगर मैं शुक्रवार को नौकरी चलाता हूं, तो उसे सोमवार की तारीख लेनी होगी और लेनदेन को संसाधित करना होगा।एसक्यूएल सर्वर

मैं नीचे दिए गए क्वेरी का इस्तेमाल किया है पिछले व्यापार की तारीख पाने के लिए

Select Convert(varchar(50), Position_ID) as Position_ID, 
     TransAmount_Base, 
     Insert_Date as InsertDate 
    from tblsample 
Where AsOfdate = Dateadd(dd, -1, Convert(datetime, Convert(varchar(10), '03/28/2012', 101), 120)) 
Order By Position_ID 

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

उत्तर

33
SELECT DATEADD(DAY, CASE DATENAME(WEEKDAY, GETDATE()) 
         WHEN 'Sunday' THEN -2 
         WHEN 'Monday' THEN -3 
         ELSE -1 END, DATEDIFF(DAY, 0, GETDATE())) 

मैं के रूप में यह DATEFIRST स्थापना के लिए की जरूरत को हटा और सुनिश्चित करता है कि स्थानीय मशीन पर समय/दिनांक सेटिंग में बदलाव परिणामों को प्रभावित नहीं करते DATEPART पर इस जैसी चीजों के लिए DATENAME उपयोग करने के लिए पसंद करते हैं। अंत में DATEDIFF(DAY, 0, GETDATE())GETDATE() के समय भाग को वर्चर (बहुत धीमी) में बदलने की आवश्यकता को हटा देगा।


संपादित करें (लगभग 2 साल पर)

इस उत्तर बहुत मेरी अतः कैरियर की शुरुआत में ही था और यह मेरे हर गुस्सा दिलाती यह upvoted हो जाता है क्योंकि मैं अब DATENAME का उपयोग कर के भावना के साथ सहमत हैं।

एक बहुत अधिक rubust समाधान होगा:

SELECT DATEADD(DAY, CASE (DATEPART(WEEKDAY, GETDATE()) + @@DATEFIRST) % 7 
         WHEN 1 THEN -2 
         WHEN 2 THEN -3 
         ELSE -1 
        END, DATEDIFF(DAY, 0, GETDATE())); 

यह सब भाषा और DATEFIRST सेटिंग्स के लिए काम करेंगे।

+0

'DATEFIRST' को जानने की आवश्यकता से बचने के लिए 'DATENAME' का उपयोग करना, फिर भी यह अनदेखा करना कि यह भाषा विशिष्ट है? –

+0

बहुत अच्छा बिंदु। हालांकि, मैं उन परिदृश्यों में आया हूं जहां DATEFIRST संघर्ष उन परिदृश्यों से एक मुद्दा रहा है जहां भाषा संघर्ष एक मुद्दा रहा है। उदाहरण के लिए, यदि आप अपने डेटाबेस में यूडीएफ बनाना चाहते हैं तो आप पहले यूडीएफ के भीतर दिनांक परिभाषित नहीं कर पाएंगे, आप फ़ंक्शन को सही डेटफर्स्ट सेट करने के लिए कॉल करने वाले प्रश्न पर निर्भर होंगे (या एक अलग डेटफर्स्ट सेट नहीं करते), मैं इसे एक और भाषा को एक अलग भाषा (मेरे अनुभव में) सेट करने की तुलना में एक अलग डेटफर्स्ट सेट करने की आवश्यकता होगी। – GarethD

+1

आगे विस्तार करने के लिए, मैं एक ऐसी कंपनी में काम करता था जहां कमीशन सप्ताह बुधवार को पेपर की बिक्री के लिए बुधवार को चला जाता है, और टेलीसेल्स के लिए शुक्रवार से शनिवार तक, हम उसी प्रश्न का उपयोग करके डेटफर्स्ट सेट करके इस पर रिपोर्ट करने के लिए उपयोग कर सकते हैं, यह प्रस्तुत किया होगा सप्ताहांत की पहचान करने के लिए DATEPART (DAY, [date]) का कोई भी उपयोग बेकार है। यही कारण है कि मैं ** डेटानाम का उपयोग करने के लिए ** पसंद करते हैं। मैं वकालत नहीं करता कि यह निर्दोष है। – GarethD

0
select 
    dateadd(dd, 
      case DATEPART(dw, getdate()) 
      when 1 
      then -2 
      when 2 
      then -3 
      else -1 
     end, GETDATE()) 
+0

DatePart (का उपयोग करते हुए 'DW ...' 'DATEFIRST' सेटिंग जानने के बिना [अस्पष्ट] (http: //msdn.microsoft.com/en-us/library/ms174420.aspx)। ऐसा नहीं करें। –

1

पिछले व्यावसायिक दिन को खोजने का सबसे आसान समाधान calendar table का उपयोग IsBusinessDay या किसी समान नामक कॉलम के साथ करना है। आपकी क्वेरी कुछ इस तरह है:

select max(BaseDate) 
from dbo.Calendar c 
where c.IsBusinessDay = 0x1 and c.BaseDate < @InputDate 

कार्यों का उपयोग कर के साथ समस्या यह है कि आप किसी भी कारण के लिए अपवाद (राष्ट्रीय अवकाश आदि) बनाने के लिए कोड जल्दी से unmaintainable हो जाता है जब (नहीं तो); तालिका के साथ, आप केवल UPDATE एक एकल मान। एक तालिका भी "एक्स और वाई तिथियों के बीच कितने व्यावसायिक दिन हैं" जैसे सवालों के जवाब देने में बहुत आसान बनाता है, जो रिपोर्टिंग कार्यों में काफी आम हैं।

3

तो कैसे के बारे में: उपरोक्त सुझावों के लिए

declare @dt datetime='1 dec 2012' 

select case when [email protected]@DATEFIRST=DATEPART(dw,@dt) 
      then DATEADD(d,-2,@dt) 
     when ([email protected]@DATEFIRST)%7=DATEPART(dw,@dt)%7 
      then DATEADD(d,-3,@dt) 
     else DATEADD(d,-1,@dt) 
    end 
0

धन्यवाद, मैं में मेरे उपयोगकर्ता पिछले व्यापार की तारीख के लिए सभी मूल्यों की जरूरत है कि प्रश्न पर एक मामूली संस्करण था। उदाहरण के लिए, आज सोमवार है इसलिए उसे पिछले शुक्रवार को मध्यरात्रि से शनिवार को आधी रात को सब कुछ चाहिए। मैंने उपरोक्त के कॉम्बो और "बीच" का उपयोग करके ऐसा किया, अगर कोई दिलचस्पी लेता है। मैं एक विशाल तकनीक नहीं हूँ।

-- Declare a variable for the start and end dates. 
declare @StartDate as datetime 
declare @EndDate as datetime 

SELECT @StartDate = DATEADD(DAY, CASE DATENAME(WEEKDAY, GETDATE()) 
WHEN 'Sunday' THEN -2 
WHEN 'Monday' THEN -3 
    ELSE -1 END, DATEDIFF(DAY, 0, GETDATE())) 
select @EndDate = @StartDate + 1 
select @StartDate , @EndDate 
-- Later on in the query use "between" 
and mydate between @StartDate and @EndDate 
1

आप आसानी से यह एक फ़ंक्शन कॉल कर सकते हैं, जो भी इच्छित तिथि के साथ GetDate() को प्रतिस्थापित करने के लिए दूसरा पैरा जोड़ सकता है। यदि आप GetDate() बदलते हैं, तो यह सप्ताह के किसी भी दिन, किसी भी दिनांक सीमा पर काम करेगा। यह तिथि में परिवर्तन नहीं होगा अगर सप्ताह के दिन इनपुट तारीख है (GetDate())

Declare @DayOfWeek As Integer = 2 -- Monday 

Select DateAdd(Day, ((DatePart(dw,GetDate()) + (7 - @DayOfWeek)) * -1) % 7, Convert(Date,GetDate())) 
संबंधित मुद्दे