2010-07-20 10 views
5

" मेरे पास टाइमस्टैम्प के साथ एक टेबल है, और मैं इस तालिका को घंटे-अंतराल अंतराल में विभाजित करना चाहता हूं, अभी से चल रहा हूं और जा रहा हूं कुछ घंटों के पीछे। मैं टी-एसक्यूएल DATEDIFF फ़ंक्शन के साथ आवश्यक परिणामों को प्राप्त करने में असमर्थ हूं, क्योंकि यह दो तारीखों के बीच 12 मिनट गुजरने की संख्या की गणना करता है - मुझे लगता है कि उन्हें कितनी बार हाथ हाथ पास करता है, जहां यह अब है टाइमस्टैम्प और अब के बीचटी-एसक्यूएल डेटडिफ - "पूर्ण घंटे पहले" से विभाजन "

क्या टी-एसक्यूएल में ऐसा करने का एक सीधा तरीका है?

अद्यतन: टिप्पणियों के जवाब में, यहाँ कुछ नमूना डेटा, क्वेरी मैं वर्तमान में उपयोग कर रहा हूँ और परिणाम मैं हो रही है, साथ ही परिणाम मैं चाहता है।

नमूना डेटा:

TimeStamp 
********* 
2010-07-20 11:00:00.000 
2010-07-20 10:44:00.000 
2010-07-20 10:14:00.000 
2010-07-20 11:00:00.000 
2010-07-20 11:40:00.000 
2010-07-20 10:16:00.000 
2010-07-20 13:00:00.000 
2010-07-20 12:58:00.000 

वर्तमान क्वेरी:

SELECT TimeStamp, DATEDIFF(HOUR, TimeStamp, CURRENT_TIMESTAMP) AS Diff FROM ... 

परिणाम:

 TimeStamp     Diff 
    *********     **** 
    2010-07-20 11:00:00.000  2 
    2010-07-20 10:44:00.000  3 
    2010-07-20 10:14:00.000  3 
    2010-07-20 11:00:00.000  2 
    2010-07-20 11:40:00.000  2 
    2010-07-20 10:16:00.000  3 
    2010-07-20 13:00:00.000  0 
    2010-07-20 12:58:00.000  1

क्या मैं नहीं बल्कि होगा:

 -- The time is now, for the sake of the example, 13:40 

    TimeStamp     Diff 
    *********     **** 
    2010-07-20 11:00:00.000  3 -- +1 
    2010-07-20 10:44:00.000  3 
    2010-07-20 10:14:00.000  4 -- +1 
    2010-07-20 11:00:00.000  3 -- +1 
    2010-07-20 11:40:00.000  2 or 3 -- edge case, I don't really care which 
    2010-07-20 10:16:00.000  4 -- +1 
    2010-07-20 13:00:00.000  1 -- +1 
    2010-07-20 12:58:00.000  1

मैंने उन परिणामों को चिह्नित किया है जो +1 के साथ बदल गए हैं। इसके अलावा, मैं वास्तव में परवाह नहीं है अगर यह 0 से इंडैक्स या 1 से इंडैक्स, लेकिन मूल रूप से, अगर यह अब 13:40 मैं

 12:40-13:40 1 (or 0) 
    11:40-12:40 2 (or 1) 
    10:40-11:40 3 (or 2) 
    09:40-10:40 4 (or 3)
+0

आप व्याख्या कर सकते हैं कि साथ इनपुट डेटा और उम्मीद उत्पादन के साथ प्रश्न, आपने लिखा है? – shahkalpesh

+0

मिनटों में DATEDIFF फिर 60 से पूर्णांक विभाजन? –

उत्तर

7

होने की समयावधियों है कि एक ही मूल्य मिल चाहते हैं आप नहीं कर सकते है बस DATEDIFF(minute,.. का उपयोग करें और फिर परिणाम 60 को विभाजित करें और पूर्णांक मान लें। जैसे

SELECT DATEDIFF(minute, '2010-07-20 06:00', GETDATE())/60 

मेरा मानना ​​है कि के रूप में DateDiff किसी पूर्णांक रिटर्न इस परोक्ष किसी पूर्णांक के रूप में कास्ट किया जाएगा, यह कोई राउंडिंग साथ पूरे घंटे देता है।

अपने अपडेट किए गए पोस्ट के लिए अपनी सटीक क्वेरी उपयोग करने के लिए:

SELECT TimeStamp, (DATEDIFF(minute, TimeStamp, CURRENT_TIMESTAMP) /60) AS Diff FROM ... 
+0

यह अभी भी सटीक नहीं होगा। आपने अभी त्रुटि को 59 मिनट से 59 सेकंड में बदल दिया है ... – ErikE

+0

@Emtucifor: 59 सेकंड की त्रुटि अभी भी बहुत बेहतर है - मैं यह तय करने के लिए इसका उपयोग करने जा रहा हूं कि उपयोगकर्ता को अधिसूचना प्राप्त होनी चाहिए या नहीं, और उन्हें केवल प्रति घंटे सबसे ज्यादा मिलना चाहिए। उस मामले में 59 मिनट की त्रुटि आपदाजनक है - 59 सेकंड की त्रुटि बहुत अच्छी है। और मैं भी मिनटों के साथ एक ही चीज़ कर कर त्रुटि को छोटा (<1 सेकंड) भी प्राप्त कर सकता हूं क्योंकि बेन मिनटों के साथ करता है। –

+0

ठीक है, फिर कोई समस्या नहीं है। मुझे तारीखों को कम करने के मेरे संस्करण को बेहतर पसंद है, हालांकि, क्योंकि यह भी आसान है और यह डेटा प्रकार की अनुमति के समान सटीक है। :) – ErikE

0

आप कर सकते हैं इस पर समूह:

SELECT DateDiff(Hour, 0, GetDate() - TimeStamp) 

तुम समय का प्रतिनिधित्व करता है यह जानना चाहते हैं, उसे वापस calc:

DateAdd(Hour, -DateDiff(Hour, 0, GetDate() - TimeStamp), GetDate()) 

यदि आप तिथियों को घटाना पसंद नहीं करते हैं, तो यह अभी भी किया जा सकता है लेकिन थोड़ा कठिन हो जाता है। अंधेरे में शूट करने के बजाय मैंने यह साबित करने के लिए एक प्रश्न तैयार किया कि यह सही है।

SELECT 
    TimeStamp, 
    Now = GetDate(), 
    HourDiff = DateDiff(Hour, 0, GetDate() - TimeStamp), 
    HourCalc = DateAdd(Hour, -DateDiff(Hour, 0, GetDate() - TimeStamp), GetDate()), 
    HourDiff2 = DateDiff(Hour, DateAdd(Millisecond, AdjustMs, TimeStamp), DateAdd(Millisecond, AdjustMs, GetDate())), 
    HourCalc2 = DateAdd(Hour, -DateDiff(Hour, DateAdd(Millisecond, AdjustMs, TimeStamp), DateAdd(Millisecond, AdjustMs, GetDate())), GetDate()) 
FROM 
    (
     SELECT DateAdd(Second, -3559, GetDate()) 
     UNION ALL SELECT DateAdd(Second, -3600, GetDate()) 
     UNION ALL SELECT DateAdd(Second, -3601, GetDate()) 
    ) x (TimeStamp) 
    CROSS JOIN (
     SELECT 3599997 - DateDiff(Millisecond, 0, DateAdd(Hour, -DateDiff(Hour, 0, GetDate()), GetDate())) 
    ) D (AdjustMs) 

दुर्भाग्य से, मैं datetime डेटाप्रकार के संकल्प की मेरी जानकारी (1/एक दूसरे की 300 वीं) इस प्रकार 3,600,000 फायदा उठाने के लिए, था - 3 = 3599997. मिलीसेकंड समायोजन (GetDate के बजाय टाइमस्टैम्प के आधार पर गणना की गई थी तो) तो इसकी आवश्यकता नहीं होगी, लेकिन यह बहुत गड़बड़ होगा क्योंकि व्युत्पन्न तालिका डी के अंदर बड़ी अभिव्यक्ति को मुख्य प्रश्न में दो बार उपयोग करना होगा, एडजस्टम्स को बदलना होगा।

गणना आवश्यक लगने से अधिक जटिल होती है क्योंकि आप यादृच्छिक तिथियों के बीच मिलीसेकंड अंतर की गणना नहीं कर सकते हैं या आपको ओवरफ़्लो त्रुटि मिल जाएगी। यदि आप जानते हैं कि तिथि सीमा संभव है तो आप '1 9 000101 00: 00: 00.000' (उपरोक्त अभिव्यक्तियों में 0) की तुलना में एक अलग एंकर तिथि का उपयोग करके प्रत्यक्ष मिलीसेकंड गणना करने से दूर हो सकते हैं।

दूसरी सोचा पर, आप केवल में एक हस्ताक्षरित लंबे मिलीसेकंड के 24 + दिनों मिलती है:

SELECT DateAdd(Millisecond, 2147483647, 0) = '1900-01-25 20:31:23.647' 
+0

ऐसा लगता है कि तारीखों को घटाने से बचने के लिए एक लंबा रास्ता तय करना है - लेकिन आपकी पोस्ट से मैं इसे लेता हूं, ऐसा करने के लिए अच्छे कारण हो सकते हैं। मैं तिथियों को घटाना क्यों नहीं चाहूंगा? –

+0

ठीक है, इस मामले में ** डेटाटाइम ** के साथ इसकी आवश्यकता नहीं है, लेकिन SQL सर्वर 2008 में आप ** दिनांक ** डेटा प्रकार के मानों को जोड़ या घटा नहीं सकते हैं। हालांकि ** डेटाटाइम ** के साथ ऐसा करने के लिए अभी काम करता है, यह हमेशा के लिए नहीं हो सकता है। सी # .Net यह भी मना करता है (आप केवल तारीखों या अन्य टाइमपैंस से टाइमपैन जोड़ सकते हैं और घटा सकते हैं) इसलिए हम सभी को इससे बचने के तरीकों के बारे में सोचना चाहिए यदि हम इस सामान के लंबे समय तक रहने के लिए जा रहे हैं। कुछ दिन डेटाटाइम घटाकर हटाया जा सकता है और फिर फीचर के रूप में हटा दिया जा सकता है! – ErikE

0

मैं

FLOOR(24 * CAST(CURRENT_TIMESTAMP-[TimeStamp] as float)) 

टेस्ट केस

DECLARE @GetDate datetime 
set @GetDate = '2010-07-20 13:40:00.000'; 

WITH TestData As 
(
select CAST('2010-07-20 11:00:00.000' AS DATETIME) AS [TimeStamp] UNION ALL 
select '2010-07-20 10:44:00.000' UNION ALL  
select '2010-07-20 10:14:00.000' UNION ALL 
select '2010-07-20 11:00:00.000' UNION ALL 
select '2010-07-20 11:40:00.000' UNION ALL 
select '2010-07-20 10:16:00.000' UNION ALL 
select '2010-07-20 13:00:00.000' UNION ALL 
select '2010-07-20 12:58:00.000' 
) 

SELECT [TimeStamp], FLOOR(24 * CAST(@GetDate-[TimeStamp] as float)) AS Diff 
FROM TestData 

का उपयोग करेंगे परिणाम

(आप 1 जोड़ने के लिए सटीक परिणाम आप पोस्ट प्राप्त करने के लिए की आवश्यकता होगी, लेकिन आप कहते हैं कि आप के बारे में 0 या 1 अनुक्रमित परवाह नहीं कर रहे हैं)

TimeStamp    Diff 
----------------------- ---------------------- 
2010-07-20 11:00:00.000 2 
2010-07-20 10:44:00.000 2 
2010-07-20 10:14:00.000 3 
2010-07-20 11:00:00.000 2 
2010-07-20 11:40:00.000 2 
2010-07-20 10:16:00.000 3 
2010-07-20 13:00:00.000 0 
2010-07-20 12:58:00.000 0 
+0

क्यों '24 *'? 'सीएएसटी (@ गेटडेट- [टाइमस्टैम्प] एएस फ्लोट क्या है)' मुझे दे दो? –

+0

@ टोमास। 'सीएएसटी (@ गेटडेट- [टाइमस्टैम्प] एएस फ्लोट) 'दिनों के अंतर की संख्या है। जैसे 1.75 1 दिन और 18 घंटे का अंतर होगा। तो 24 से गुणा करने से घंटे के अंतर की संख्या मिलती है। 'फ़्लोर' का उपयोग करके एक साथ एक घंटे में सब कुछ समूह। –

+0

मार्टिन, मेरे अनुभव में फ्लोट में कनवर्ट करना डेटाटाइम के लिए विश्वसनीय नहीं है। मैंने अतीत में इस बात का अध्ययन किया। डेटीफ (घंटा, 0, Current_TimeStamp - टाइमस्टैम्प) एक ही चाल करता है। – ErikE

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