एक समय सीमा के भीतर 5 मिनट के अंतराल में समूह बनाना


93

मुझे mySQL कमांड्स के साथ कुछ कठिनाइयां हैं जो मैं करना चाहता हूं।

SELECT a.timestamp, name, count(b.name) 
FROM time a, id b 
WHERE a.user = b.user
  AND a.id = b.id
  AND b.name = 'John'
  AND a.timestamp BETWEEN '2010-11-16 10:30:00' AND '2010-11-16 11:00:00' 
GROUP BY a.timestamp

यह मेरा वर्तमान आउटपुट स्टेटमेंट है।

timestamp            name  count(b.name)
-------------------  ----  -------------
2010-11-16 10:32:22  John  2
2010-11-16 10:35:12  John  7
2010-11-16 10:36:34  John  1
2010-11-16 10:37:45  John  2
2010-11-16 10:48:26  John  8
2010-11-16 10:55:00  John  9
2010-11-16 10:58:08  John  2

मैं उन्हें 5 मिनट के अंतराल के परिणामों में कैसे समूहित करूं?

मैं चाहता हूं कि मेरा आउटपुट जैसा हो

timestamp            name  count(b.name)
-------------------  ----  -------------
2010-11-16 10:30:00  John  2
2010-11-16 10:35:00  John  10
2010-11-16 10:40:00  John  0
2010-11-16 10:45:00  John  8
2010-11-16 10:50:00  John  0
2010-11-16 10:55:00  John  11 

जवाबों:


146

यह हर अंतराल के साथ काम करता है।

PostgreSQL

SELECT
    TIMESTAMP WITH TIME ZONE 'epoch' +
    INTERVAL '1 second' * round(extract('epoch' from timestamp) / 300) * 300 as timestamp,
    name,
    count(b.name)
FROM time a, id 
WHEREGROUP BY 
round(extract('epoch' from timestamp) / 300), name


माई एसक्यूएल

SELECT
    timestamp,  -- not sure about that
    name,
    count(b.name)
FROM time a, id 
WHEREGROUP BY 
UNIX_TIMESTAMP(timestamp) DIV 300, name

ओह ...
mysql-

2
ठीक है .. अर्क के बजाय .. ग्रुप बाय राउंड (UNIX_TIMESTAMP (टाइमस्टैम्प) / 300) को ट्रिक करना चाहिए
boecko

2
@ pHiL की टिप्पणी mySql पर सही है, आपको गोल (/) के बजाय DIV का उपयोग करना चाहिए अन्यथा अंतराल के बीच की सीमा गलत है
डेविड मार्क

1
बस इसे कई डेटासेट्स के साथ आज़माया गया और दूसरी क्वेरी MySQL के लिए शानदार ढंग से काम करती है, जो ओपीएस की चिंता थी। चूंकि @sky अनुपस्थित लगता है, क्या हमें इस पर एक समूह की सहमति मिल सकती है?
जॉय टी

1
मैंने भी यही कोशिश की है। इसका पहला रिकॉर्ड हर बार 2 मिनट या 3 मिनट के अंतराल और आगे के 5 मिनट के अंतराल को गलत दिखाता है। नोट: - मैंने पिछले 15 मिनट के रिकॉर्ड प्राप्त करने के लिए एक शर्त जोड़ी है।
रितेश

33

मैं उसी मुद्दे पर आया था।

मैंने पाया कि किसी भी मिनट के अंतराल से समूह बनाना आसान है, बस सेकंड की मात्रा में मिनटों द्वारा युग को विभाजित करना है और फिर शेष की सवारी प्राप्त करने के लिए या तो गोलाई या फर्श का उपयोग करना है। इसलिए यदि आप 5 मिनट में अंतराल प्राप्त करना चाहते हैं तो आप 300 सेकंड का उपयोग करेंगे ।

    SELECT COUNT(*) cnt, 
    to_timestamp(floor((extract('epoch' from timestamp_column) / 300 )) * 300) 
    AT TIME ZONE 'UTC' as interval_alias
    FROM TABLE_NAME GROUP BY interval_alias
interval_alias       cnt
-------------------  ----  
2010-11-16 10:30:00  2
2010-11-16 10:35:00  10
2010-11-16 10:45:00  8
2010-11-16 10:55:00  11 

यह चयनित मिनट अंतराल द्वारा डेटा को सही ढंग से समूह में लौटाएगा; हालाँकि, यह उन अंतरालों को वापस नहीं करेगा जिनमें कोई डेटा नहीं है। उन खाली अंतरालों को प्राप्त करने के लिए हम फंक्शन जेनरेट_सरीज का उपयोग कर सकते हैं ।

    SELECT generate_series(MIN(date_trunc('hour',timestamp_column)),
    max(date_trunc('minute',timestamp_column)),'5m') as interval_alias FROM 
    TABLE_NAME

परिणाम:

interval_alias       
-------------------    
2010-11-16 10:30:00  
2010-11-16 10:35:00
2010-11-16 10:40:00   
2010-11-16 10:45:00
2010-11-16 10:50:00   
2010-11-16 10:55:00   

अब शून्य घटनाओं के साथ परिणाम प्राप्त करने के लिए हम केवल बाहरी दोनों परिणाम सेट में शामिल होते हैं

    SELECT series.minute as interval,  coalesce(cnt.amnt,0) as count from 
       (
       SELECT count(*) amnt,
       to_timestamp(floor((extract('epoch' from timestamp_column) / 300 )) * 300)
       AT TIME ZONE 'UTC' as interval_alias
       from TABLE_NAME  group by interval_alias
       ) cnt
    
    RIGHT JOIN 
       (    
       SELECT generate_series(min(date_trunc('hour',timestamp_column)),
       max(date_trunc('minute',timestamp_column)),'5m') as minute from TABLE_NAME 
       ) series
  on series.minute = cnt.interval_alias

अंतिम परिणाम में सभी 5 मिनट के अंतराल के साथ श्रृंखला शामिल होगी, यहां तक ​​कि जिनके पास कोई मूल्य नहीं है।

interval             count
-------------------  ----  
2010-11-16 10:30:00  2
2010-11-16 10:35:00  10
2010-11-16 10:40:00  0
2010-11-16 10:45:00  8
2010-11-16 10:50:00  0 
2010-11-16 10:55:00  11 

अन्तराल को आसानी से Gener_series के अंतिम पैरामीटर को समायोजित करके बदला जा सकता है। हमारे मामले में हम '5 मी' का उपयोग करते हैं लेकिन यह कोई अंतराल हो सकता है जिसे हम चाहते हैं।


1
अगर यह MySQL होता तो ऐसा होता। Gener_series की तरह लगता है एक PostgreSQL फ़ंक्शन है। बहुत बुरा।
एंड्रियास

पहली क्वेरी जो केवल वर्तमान डेटा केवल परिणाम दे रही है, यह दोनों समय अवधि में 2 समय अवधि के मध्य रिकॉर्ड की गणना करता है। जैसे 2 समयावधि, 10:35 और 10:40 में, यह दोनों समूहों में 10:40 गिना जाता है, जो 10:35 से 10:40 और 10:40 से 10:45 तक एक है।
प्रेम पोपटिया

29

आपको GROUP BY UNIX_TIMESTAMP(time_stamp) DIV 300राउंड के बजाय (../ 300) का उपयोग करना चाहिए क्योंकि राउंडिंग के बाद मैंने पाया कि कुछ रिकॉर्ड दो समूहित परिणाम सेटों में गिने जाते हैं।


थिस राउंड सही है (../ 300)
mySql

1
जो लोग उत्सुक हैं, उनके लिए DIVMySQL floor()एक फ्लोट डिवीजन है जो BIGINTs के साथ सुरक्षित है ।
एरिक एल।

1
मैंने भी यही कोशिश की है। इसका पहला रिकॉर्ड हर बार 2 मिनट या 3 मिनट के अंतराल और आगे के 5 मिनट के अंतराल को गलत दिखाता है। नोट: - मैंने पिछले 15 मिनट के रिकॉर्ड प्राप्त करने के लिए एक शर्त जोड़ी है।
रितेश

राउंड के बजाय किसी को TRUNCATE या FLOOR का उपयोग करना चाहिए क्योंकि गोलाई का व्यवहार अच्छी तरह से परिभाषित नहीं है और यह प्रयुक्त C लाइब्रेरी पर निर्भर करता है। lists.mysql.com/mysql/93613
MrLeeh

28

के लिए postgres , मैं यह आसान और अधिक उपयोग करने के लिए सही पाया

date_trunc

समारोह, जैसे:

select name, sum(count), date_trunc('minute',timestamp) as timestamp
FROM table
WHERE xxx
GROUP BY name,date_trunc('minute',timestamp)
ORDER BY timestamp

आप 'मिनट', 'घंटा', 'दिन' आदि जैसे विभिन्न प्रस्तावों को प्रदान कर सकते हैं ... आज तक।


7
@tmarthal - इसे अपवित्र नहीं किया जाना चाहिए। मूल प्रश्न mysql के लिए था।
बगेडकॉम

30
आप 5यहां 5 मिनट के अंतराल के लिए कहां सेट करते हैं?
वृद्ध

उपरोक्त के लिए, WHERE क्लॉज़ को इसमें बदलें: WHERE टाइमस्टैम्प> current_timestamp - अंतराल '5 मिनट'
ल्यूक स्मिथ

2
यह प्रश्न ऐसा नहीं लगता है जो पूछा गया है, सवाल 'हर 5' मिनट है अब से 5 मिनट पहले नहीं। जवाब फिट होने के लिए
मोहम्मद रफ़ीक

11

क्वेरी कुछ इस तरह होगी:

SELECT 
  DATE_FORMAT(
    MIN(timestamp),
    '%d/%m/%Y %H:%i:00'
  ) AS tmstamp,
  name,
  COUNT(id) AS cnt 
FROM
  table
GROUP BY ROUND(UNIX_TIMESTAMP(timestamp) / 300), name

4

आप शायद अपने टाइमस्टैम्प को ymd में तोड़ने जा रहे हैं: HM और DIV 5 का उपयोग करके मिनटों को 5 मिनट के डिब्बे में विभाजित करें - कुछ इस तरह

select year(a.timestamp), 
       month(a.timestamp), 
       hour(a.timestamp), 
       minute(a.timestamp) DIV 5,
       name, 
       count(b.name)
FROM time a, id b
WHERE a.user = b.user AND a.id = b.id AND b.name = 'John' 
      AND a.timestamp BETWEEN '2010-11-16 10:30:00' AND '2010-11-16 11:00:00'
GROUP BY year(a.timestamp), 
       month(a.timestamp), 
       hour(a.timestamp), 
       minute(a.timestamp) DIV 12

... और फिर क्लाइंट कोड में आउटपुट को आपके पसंद के तरीके के रूप में प्रदर्शित करने के लिए। या, यदि आप चाहें, तो अलग-अलग कॉलम प्राप्त करने के sql concat ऑपरेटर का उपयोग करके आप पूरी तारीख स्ट्रिंग का निर्माण कर सकते हैं।

select concat(year(a.timestamp), "-", month(a.timestamp), "-" ,day(a.timestamp), 
       " " , lpad(hour(a.timestamp),2,'0'), ":", 
       lpad((minute(a.timestamp) DIV 5) * 5, 2, '0'))

... और फिर उस पर समूह


हम्मम ... लेकिन आउटपुट नहीं मिल रहा है जो मैं पाने की कोशिश कर रहा हूं। यह एक कॉलम लौटाता है और मुझे बहुत यकीन नहीं है कि गिनती का मूल्य क्या है ...
आकाश

2

यकीन नहीं होता अगर आपको अभी भी इसकी आवश्यकता है।

SELECT FROM_UNIXTIME(FLOOR((UNIX_TIMESTAMP(timestamp))/300)*300) AS t,timestamp,count(1) as c from users GROUP BY t ORDER BY t;

2016-10-29 19:35:00 | 2016-10-29 19:35:50 | 4 |

2016-10-29 19:40:00 | 2016-10-29 19:40:37 | 5 |

2016-10-29 19:45:00 | 2016-10-29 19:45:09 | 6 |

2016-10-29 19:50:00 | 2016-10-29 19:51:14 | 4 |

2016-10-29 19:55:00 | 2016-10-29 19:56:17 | 1 |


1

इसके बारे में क्या खयाल है:

select 
    from_unixtime(unix_timestamp(timestamp) - unix_timestamp(timestamp) mod 300) as ts,  
    sum(value)
from group_interval 
group by ts 
order by ts
;

0

मुझे पता चला कि MySQL के साथ शायद सही क्वेरी निम्नलिखित है:

SELECT SUBSTRING( FROM_UNIXTIME( CEILING( timestamp /300 ) *300,  
                                 '%Y-%m-%d %H:%i:%S' ) , 1, 19 ) AS ts_CEILING,
SUM(value)
FROM group_interval
GROUP BY SUBSTRING( FROM_UNIXTIME( CEILING( timestamp /300 ) *300,  
                                   '%Y-%m-%d %H:%i:%S' ) , 1, 19 )
ORDER BY SUBSTRING( FROM_UNIXTIME( CEILING( timestamp /300 ) *300,  
                                   '%Y-%m-%d %H:%i:%S' ) , 1, 19 ) DESC

आप क्या सोचते हैं मुझे बताओ।


0
select 
CONCAT(CAST(CREATEDATE AS DATE),' ',datepart(hour,createdate),':',ROUNd(CAST((CAST((CAST(DATEPART(MINUTE,CREATEDATE) AS DECIMAL (18,4)))/5 AS INT)) AS DECIMAL (18,4))/12*60,2)) AS '5MINDATE'
,count(something)
from TABLE
group by CONCAT(CAST(CREATEDATE AS DATE),' ',datepart(hour,createdate),':',ROUNd(CAST((CAST((CAST(DATEPART(MINUTE,CREATEDATE) AS DECIMAL (18,4)))/5 AS INT)) AS DECIMAL (18,4))/12*60,2))

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