2013-01-21 16 views
9

मुझे समय, मिनट, सेकेंड और औसत लंबाई के संदर्भ में कुल लंबाई की गणना करने की आवश्यकता है, प्रारंभिक समय और समाप्ति समय के साथ कुछ डेटा दिया गया है।एचएच में डेटाडिफ़: एमएम: एसएस प्रारूप

उदाहरण के लिए परिणाम 45:15:10 जैसा होना चाहिए जिसका अर्थ है 45 घंटे 15 मिनट 10 सेकंड, या 30:07 30 मिनट 07 सेकंड के लिए।

हम SQL Server 2008 R2 का उपयोग कर रहे हैं और समय 24:59:59 से अधिक होने पर रूपांतरण विफल हुआ। किसी भी विचार के बारे में मैं यह कैसे कर सकता था?

जानकारी के लिए, तालिका में कॉलम Id, StartDateTime, EndDateTime कर रहे हैं, आदि मैं एक मासिक रिपोर्ट जो रिकॉर्डिंग महीने के गिनती में शामिल है, इन रिकॉर्ड की कुल लंबाई, और औसत लंबाई बनाने की जरूरत है। मैं जानना चाहता हूं कि यह सब करने का एक आसान तरीका है या नहीं।

+2

सब कुछ सेकंड में कनवर्ट करें, इसे समेटें और फिर मैन्युअल रूप से पठनीय प्रारूप में कनवर्ट करें। – Kermit

उत्तर

5

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

DECLARE @d TABLE 
(
    id INT IDENTITY(1,1), 
    StartDateTime DATETIME, 
    EndDateTime DATETIME 
); 

INSERT @d(StartDateTime, EndDateTime) VALUES 
(DATEADD(DAY, -2, GETDATE()), DATEADD(MINUTE, 15, GETDATE())), 
(GETDATE()     , DATEADD(MINUTE, 22, GETDATE())), 
(DATEADD(DAY, -1, GETDATE()), DATEADD(MINUTE, 5, GETDATE())), 
(DATEADD(DAY, -4, GETDATE()), DATEADD(SECOND, 14, GETDATE())); 

;WITH x AS (SELECT id, StartDateTime, EndDateTime, 
    d = DATEDIFF(SECOND, StartDateTime, EndDateTime), 
    a = AVG(DATEDIFF(SECOND, StartDateTime, EndDateTime)) OVER() 
    FROM @d 
) 
SELECT id, StartDateTime, EndDateTime, 
    [delta_HH:MM:SS] = CONVERT(VARCHAR(5), d/60/60) 
    + ':' + RIGHT('0' + CONVERT(VARCHAR(2), d/60%60), 2) 
    + ':' + RIGHT('0' + CONVERT(VARCHAR(2), d % 60), 2), 
    [avg_HH:MM:SS] = CONVERT(VARCHAR(5), a/60/60) 
    + ':' + RIGHT('0' + CONVERT(VARCHAR(2), a/60%60), 2) 
    + ':' + RIGHT('0' + CONVERT(VARCHAR(2), a % 60), 2) 
FROM x; 

परिणाम:

id StartDateTime  EndDateTime   delta_HH:MM:SS avg_HH:MM:SS 
-- ------------------- ------------------- -------------- ------------ 
1 2013-01-19 14:24:46 2013-01-21 14:39:46 48:15:00  42:10:33 
2 2013-01-21 14:24:46 2013-01-21 14:46:46 0:22:00  42:10:33 
3 2013-01-20 14:24:46 2013-01-21 14:29:46 24:05:00  42:10:33 
4 2013-01-17 14:24:46 2013-01-21 14:25:00 96:00:14  42:10:33 

यह ठीक नहीं है कि आप क्या पूछा, के रूप में यह सिर्फ एम.एम. दिखाई नहीं देंगे: डेल्टा < 1 घंटे के लिए एस एस। आप एक सरल CASE अभिव्यक्ति के साथ कि समायोजित कर सकते हैं:

;WITH x AS (SELECT id, StartDateTime, EndDateTime, 
    d = DATEDIFF(SECOND, StartDateTime, EndDateTime), 
    a = AVG(DATEDIFF(SECOND, StartDateTime, EndDateTime)) OVER() 
    FROM @d 
) 
SELECT id, StartDateTime, EndDateTime, 
    [delta_HH:MM:SS] = CASE WHEN d >= 3600 THEN 
    CONVERT(VARCHAR(5), d/60/60) + ':' ELSE '' END 
    + RIGHT('0' + CONVERT(VARCHAR(2), d/60%60), 2) 
    + ':' + RIGHT('0' + CONVERT(VARCHAR(2), d % 60), 2), 
    [avg_HH:MM:SS] = CASE WHEN a >= 3600 THEN 
    CONVERT(VARCHAR(5), a/60/60) + ':' ELSE '' END 
    + RIGHT('0' + CONVERT(VARCHAR(2), a/60%60), 2) 
    + ':' + RIGHT('0' + CONVERT(VARCHAR(2), a % 60), 2) 
FROM x; 

इस क्वेरी डेल्टा 0:22:00 से 22:00 के लिए ऊपर परिणाम में 2 पंक्ति में स्तंभ बदल जाता है।

1

यदि आप औसत करना चाहते हैं, तो सबसे अच्छा तरीका एक दिन के सेकंड या अंशों में परिवर्तित करना है। डे भिन्न, एसक्यूएल सर्वर में सुविधाजनक हैं क्योंकि आप की तरह कर सकते हैं:

select cast(avg(cast(endtime - starttime as float) as datetime) 
from t 

गणित में समय की जानकारी प्राप्त करने के लिए:

select avg(cast(endtime - starttime) as float) 
from t 

आप रिवर्स कलाकारों का उपयोग कर एक datetime वापस करने के लिए यह परिवर्तित कर सकते हैं प्रारूप आप चाहते हैं। । । वह दर्द है। आप अंतिम प्रारूप में दिन सहित, और उपयोग करने पर विचार हो सकता है:

select cast(floor(cast(<val> as float)*24) as varchar(255))+right(convert(varchar(255), <val>, 120), 6) 

यह मिनट और सेकंड के लिए convert का उपयोग करता है, जो होना चाहिए:

select right(convert(varchar(255), <val>, 120), 10) 

24 से अधिक घंटे पाने के लिए, यहाँ एक और तरीका है बाईं ओर 0s के साथ गद्देदार। यह घंटों को एक अलग मूल्य के रूप में जोड़ता है।

4
SELECT CONVERT(time, 
       DATEADD(mcs, 
         DATEDIFF(mcs, 
           '2007-05-07 09:53:00.0273335', 
           '2007-05-07 09:53:01.0376635'), 
         CAST('1900-01-01 00:00:00.0000000' as datetime2) 
        ) 
      ) 
0

मैंने थोड़ा अविनाश के जवाब को संशोधित किया क्योंकि अंतर बहुत बड़ा होने पर त्रुटि के साथ समाप्त हो सकता है।यदि आपको केवल एचएच की आवश्यकता है: मिमी: एसएस इस तरह के सेकंड स्तर पर अंतर करने के लिए पर्याप्त है:

SELECT CONVERT(time, 
    DATEADD(s, 
    DATEDIFF(s, 
     '2018-01-07 09:53:00', 
     '2018-01-07 11:53:01'), 
    CAST('1900-01-01 00:00:00.0000000' as datetime2) 
    ) 
) 
संबंधित मुद्दे

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