घंटे या 10 मिनट तक समूह कैसे करें


167

जब मैं करता हूं

SELECT [Date]
  FROM [FRIIB].[dbo].[ArchiveAnalog]
  GROUP BY [Date]

मैं समूह अवधि कैसे निर्दिष्ट कर सकता हूं?

एमएस SQL ​​2008

दूसरा संपादन

मैं कोशिश कर रहा हूँ

SELECT MIN([Date]) AS RecT, AVG(Value)
  FROM [FRIIB].[dbo].[ArchiveAnalog]
  GROUP BY (DATEPART(MINUTE, [Date]) / 10)
  ORDER BY RecT

परिवर्तित% 10/10। क्या मिलीसेकंड के बिना दिनांक आउटपुट बनाना संभव है?

जवाबों:


213

अंत में साथ दिया

GROUP BY
DATEPART(YEAR, DT.[Date]),
DATEPART(MONTH, DT.[Date]),
DATEPART(DAY, DT.[Date]),
DATEPART(HOUR, DT.[Date]),
(DATEPART(MINUTE, DT.[Date]) / 10)

11
मैंने इसे बनाया ROUND((DATEPART(MINUTE, DT.[Date]) / 5),0,1) * 5, ताकि जब मैं उस डेटा को
देखूं

7
वर्ष, माह और दिन को सरल बनाया जा सकता है DATE(DT.[Date])

@ कीलन मेरे लिए काम नहीं करता है - हालाँकि CONVERT (तारीख, डीटी। [दिनांक]) करता है।
दान पार्सन्सन

datepart(hour, workingPolicy.workingHours)/2.0देता है 1.5, जबकि datepart(hour, '1900-01-01 09:00:30.000')/2.0देता है 4.5, मैं क्यों समझ में नहीं आता? नोट: workingPolicy.workingHours = 1900-01-01 09: 00: 30.000 । कृपया मदद करें
affanBajwa

65

मैं पार्टी के लिए सुपर लेट हूं, लेकिन यह मौजूदा जवाबों में से किसी में भी दिखाई नहीं देता:

GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, '2000', date_column) / 10 * 10, '2000')
  • 10और MINUTEशर्तों किसी भी नंबर पर बदला जा सकता है और DATEPARTक्रमश:।
  • यह एक DATETIMEमूल्य है, जिसका अर्थ है:
    • यह लंबे समय के अंतराल पर ठीक काम करता है। (वर्षों के बीच कोई टक्कर नहीं है।)
    • इसे SELECTबयान में शामिल करने से आपके आउटपुट को आपके द्वारा निर्दिष्ट स्तर पर सुंदर आउटपुट के साथ एक कॉलम मिलेगा।
  • '2000'एक "लंगर तिथि" है जिसके चारों ओर एसक्यूएल तारीख गणित करेगा। नीचे Jereonh ने पाया कि आप पिछले एंकर ( 0) के साथ एक पूर्णांक ओवरफ़्लो का सामना करते हैं, जब आप सेकंड या मिली सेकंड द्वारा हाल ही की तारीखों को समूहीकृत करते हैं।
SELECT   DATEADD(MINUTE, DATEDIFF(MINUTE, '2000', aa.[date]) / 10 * 10, '2000')
                                                               AS [date_truncated],
         COUNT(*) AS [records_in_interval],
         AVG(aa.[value]) AS [average_value]
FROM     [friib].[dbo].[archive_analog] AS aa
GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, '2000', aa.[date]) / 10 * 10, '2000')
ORDER BY [date_truncated]

अपने डेटा फैला सदियों, तो दूसरी के लिए एक एकल लंगर दिनांक का उपयोग कर या मिलीसेकंड समूहीकरण अभी भी अतिप्रवाह का सामना करेंगे। यदि ऐसा हो रहा है, तो आप प्रत्येक पंक्ति को अपनी स्वयं की तिथि की मध्यरात्रि की तुलना में बिनिंग की लंगर लगाने के लिए कह सकते हैं:

  • DATEADD(DAY, DATEDIFF(DAY, 0, aa.[date]), 0)इसके बजाय '2000'इसका उपयोग करें जहाँ यह ऊपर दिखाई देता है। आपकी क्वेरी पूरी तरह से अपठनीय होगी, लेकिन यह काम करेगा।

  • CONVERT(DATETIME, CONVERT(DATE, aa.[date]))प्रतिस्थापन के रूप में एक विकल्प हो सकता है ।

2 32 9 4.29E + 9, इसलिए यदि आपका DATEPARTहै SECOND, तो आपको दोनों तरफ 4.3 बिलियन सेकंड मिलते हैं, या "लंगर anch 136 साल।" इसी तरह, 2 32 मिलीसेकंड is 49.7 दिन का है।
And यदि आपका डेटा वास्तव में सदियों या सहस्राब्दी तक फैला है और अभी भी दूसरे या मिलीसेकंड के लिए सटीक है ... बधाई! तुम जो भी कर रहे हो, करते रहो।


क्या किसी विशिष्ट प्रारंभ तिथि से ऐसा करना संभव होगा?
Pylander

1
@ फ़िशलैंडर ज़रूर। बस whereसे पहले एक खंड रखो group by
माइकल - व्हेयर क्ले शिर्की

2
समझा। तो क्या यह / 20 * 2020 मिनट के अंतराल के लिए डेटा इकट्ठा करने के समान होगा? क्षमा करें, मैं अभी गणित के लिए संघर्ष कर रहा हूं।
यह उतार चढ़ाव भरा

2
DATEPART के रूप में सेकंड के लिए मुझे एक त्रुटि संदेश मिलता है ( The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.)। ऐसा लगता है कि MINUTE सबसे छोटी तारीख है जिसे आप इस दृष्टिकोण के साथ उपयोग कर सकते हैं।
जीरोन्ह

1
@ जोरोन्ह, तुम सही हो। मैंने उस बारे में बात करने के लिए एक खंड जोड़ा है। tldr: बदलें 0करने के लिए '2000'(उद्धरण महत्वपूर्ण हैं!) और कोशिश SECONDफिर से।
माइकल - जहां क्ले शिर्की

17

T-SQL में आप कर सकते हैं:

SELECT [Date]
  FROM [FRIIB].[dbo].[ArchiveAnalog]
  GROUP BY [Date], DATEPART(hh, [Date])

या

मिनट के उपयोग से DATEPART(mi, [Date])

या

10 मिनट के उपयोग से DATEPART(mi, [Date]) / 10(जैसे टिमोथी ने सुझाव दिया)


1
ग्रुप BY [दिनांक], DATEPART (hh, [दिनांक]) एक गड़बड़ है, नहीं?
CND

1
@nCdy सब ठीक होना चाहिए, अन्यथा आपको एक त्रुटि मिलती है "... चयनित सूची में अमान्य है क्योंकि यह या तो कुल फ़ंक्शन या समूह द्वारा समूह में शामिल नहीं है"
tzup

1
आप एक ही समय में पूरे दिनांक और घंटे के आधार पर समूह कैसे बनाते हैं? मैं सिर्फ मिन डेट का उपयोग कर रहा हूं।
CND

यदि आप Min (दिनांक) का उपयोग करते हैं तो निश्चित रूप से आप Group By में दिनांक निकाल सकते हैं।
tzup

3
10 से विभाजित मिनट 10 मिनट के अंतराल से समूह बनाएंगे, जिसकी मुझे आवश्यकता है। मोडुलो 10 का कोई मतलब नहीं है।
टार

12

10 मिनट के अंतराल के लिए, आप करेंगे

GROUP BY (DATEPART(MINUTE, [Date]) / 10)

जैसा कि पहले ही tzup और Pieter888 द्वारा उल्लेख किया गया था ... एक घंटे का अंतराल करने के लिए, बस

GROUP BY DATEPART(HOUR, [Date])

2
लेकिन यहाँ मैं 2011 के मिनट के साथ 1980 वर्ष के समूह मिनट: एसआई इसके बारे में देखभाल करने की जरूरत है।
CND

% सही गणित होगा? ऐसा नहीं होगा कि 10 समूह बनाएं। उदाहरण के लिए: 1% 10 = 9 2% 10 = 8 यह आवश्यक रूप से सही कालानुक्रमिक समूहन भी नहीं होगा। मुझे लगता है कि सिर्फ एक सामान्य विभाजन सही होगा। जब तक% sql में शेष भाग नहीं है।
स्टीवन

12
10 से विभाजित मिनट 10 मिनट के अंतराल से समूह बनाएंगे, जिसकी मुझे आवश्यकता है। मोडुलो 10 का कोई मतलब नहीं है।
टार

टार से सहमत। समूहीकरण का कोई मतलब नहीं है।
माइकमेर्को

7

कुछ ऐसा होना चाहिए

select timeslot, count(*)  
from 
    (
    select datepart('hh', date) timeslot
    FROM [FRIIB].[dbo].[ArchiveAnalog]  
    ) 
group by timeslot

(वाक्यविन्यास के बारे में 100% निश्चित नहीं है - मैं अधिक ओरेकल तरह का आदमी हूं)

Oracle में:

SELECT timeslot, COUNT(*) 
FROM
(  
    SELECT to_char(l_time, 'YYYY-MM-DD hh24') timeslot 
    FROM
    (
        SELECT l_time FROM mytab  
    )  
) GROUP BY timeslot 

6

लेखक ने जो मूल उत्तर दिया वह बहुत अच्छा काम करता है। इस विचार को विस्तार देने के लिए, आप कुछ ऐसा कर सकते हैं

group by datediff(minute, 0, [Date])/10

जो आपको लंबी अवधि तक समूह करने की अनुमति देगा, फिर 60 मिनट, 720 कहो, जो आधा दिन है आदि।


1
उपरोक्त के लिए MySQL क्वेरी क्या होगी?
बिरंची

4

MySql के लिए:

GROUP BY
DATE(`your_date_field`),
HOUR(`your_date_field`),
FLOOR( MINUTE(`your_date_field`) / 10);

1

मेरा समाधान दिनांक अंतराल के साथ तालिका बनाने के लिए एक फ़ंक्शन का उपयोग करना है और फिर तालिका में दिनांक अंतराल का उपयोग करके मुझे जिस डेटा को समूह करना है, उस तालिका में शामिल करें। डेटा पेश करते समय तिथि अंतराल को आसानी से चुना जा सकता है।

CREATE FUNCTION [dbo].[fn_MinuteIntervals]
    (
      @startDate SMALLDATETIME ,
      @endDate SMALLDATETIME ,
      @interval INT = 1
    )
RETURNS @returnDates TABLE
    (
      [date] SMALLDATETIME PRIMARY KEY NOT NULL
    )
AS
    BEGIN
        DECLARE @counter SMALLDATETIME
        SET @counter = @startDate
        WHILE @counter <= @endDate
            BEGIN
                INSERT INTO @returnDates VALUES ( @counter )
                SET @counter = DATEADD(n, @interval, @counter)
            END
        RETURN
    END

1
declare @interval tinyint
set @interval = 30
select dateadd(minute,(datediff(minute,0,[DateInsert])/@interval)*@interval,0), sum(Value_Transaction)
from Transactions
group by dateadd(minute,(datediff(minute,0,[DateInsert])/@interval)*@interval,0)

8
Stackoverflow में आपका स्वागत है। आपको अपना उत्तर पूरी तरह से समझाने की आवश्यकता है, और इससे साइट पर पहले से मौजूद अन्य 10 उत्तरों में क्या जुड़ जाता है।
सिमोन। 19

0

SQL सर्वर 2012 के लिए, हालांकि मेरा मानना ​​है कि यह SQL Server 2008R2 में काम करेगा, मैं मिलिसेकंड के लिए नीचे समय प्राप्त करने के लिए निम्नलिखित दृष्टिकोण का उपयोग करता हूं:

DATEADD(MILLISECOND, -DATEDIFF(MILLISECOND, CAST(time AS DATE), time) % @msPerSlice, time)

यह काम करता है:

  • एक निश्चित बिंदु और लक्ष्य समय के बीच मिलीसेकंड की संख्या प्राप्त करना:
    @ms = DATEDIFF(MILLISECOND, CAST(time AS DATE), time)
  • समय के स्लाइस में उन मिलीसेकंड को विभाजित करने के शेष को लेना:
    @rms = @ms % @msPerSlice
  • टुकड़ा समय पाने के लिए लक्ष्य समय में शेष उस ऋणात्मक को जोड़ना:
    DATEADD(MILLISECOND, -@rms, time)

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

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


0
select from_unixtime( 600 * ( unix_timestamp( [Date] ) % 600 ) ) AS RecT, avg(Value)
from [FRIIB].[dbo].[ArchiveAnalog]
group by RecT
order by RecT;

आप जिस भी समूह को चाहते हैं, उसे दो 600 से बदल दें।

यदि आपको अक्सर इसकी आवश्यकता होती है और तालिका परिवर्तित नहीं होती है, जैसा कि नाम से पता चलता है, तो संभवतः तालिका में एक अंश के रूप में दिनांक (और समय) को परिवर्तित करने और संग्रहीत करने के लिए यह थोड़ा तेज़ होगा।


0

मुझे पता है कि मुझे इस शो के साथ आने में देर हो गई है, लेकिन मैंने इसका इस्तेमाल किया - बहुत आसान तरीका। यह आपको किसी भी गोल मुद्दों के बिना 60 मिनट के स्लाइस प्राप्त करने की अनुमति देता है।

Select 
   CONCAT( 
            Format(endtime,'yyyy-MM-dd_HH:'),  
            LEFT(Format(endtime,'mm'),1),
            '0' 
          ) as [Time-Slice]

0
select dateadd(minute, datediff(minute, 0, Date), 0),
       sum(SnapShotValue)
FROM [FRIIB].[dbo].[ArchiveAnalog]
group by dateadd(minute, datediff(minute, 0, Date), 0)

1
जब आप किसी प्रश्न का उत्तर दें तो कृपया कुछ स्पष्टीकरण प्रदान करें।
Shizzen83
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.