একটি সময়সীমার মধ্যে 5 মিনিটের ব্যবধানে গ্রুপিং করা


94

আমি করতে চাই এমন মাইএসকিউএল কমান্ডগুলির সাথে আমার কিছু অসুবিধা রয়েছে।

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

ওহ ... মাইএসকিএল-পতাকাটি পেলেন না .. এটি একটি পোস্টগ্র্যাস্কিল-ক্যোয়ারী .. তবে মূলত এটিও
মাইএসকিএল

4
ঠিক আছে .. এক্সট্র্যাক্টের পরিবর্তে .. রাউন্ডের মাধ্যমে গ্রুপ (ইউনিক্সটাইমস্ট্যাম্প (টাইমস্ট্যাম্প) / 300) কৌশলটি করা উচিত
বোয়েকো

4
@ পিএইচআইএল এর মন্তব্য মাইএসকিএলে ঠিক আছে আপনার বৃত্তাকার (/) পরিবর্তে ডিআইভি ব্যবহার করা উচিত অন্যথায় অন্তরগুলির মধ্যে
সীমাটি

4
এটি বেশ কয়েকটি ডেটাসেটের সাহায্যে চেষ্টা করেছেন এবং মাইএসকিউএল-র জন্য দ্বিতীয় তদন্তটি দুর্দান্তভাবে কাজ করে, যা ওপিএস উদ্বেগ ছিল। যেহেতু @ স্কাই অনুপস্থিত বলে মনে হচ্ছে, আমরা কি এই বিষয়ে একটি গ্রুপ sensকমত্য পেতে পারি উত্তরটি?
জোয়ে টি

4
আমি এটিও চেষ্টা করেছি। এটি প্রতিবার 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 

এটি নির্বাচিত মিনিটের ব্যবধানের মাধ্যমে সঠিকভাবে গোষ্ঠীটি তথ্য ফিরিয়ে দেবে; তবে এটি অন্তরগুলিকে ফিরিয়ে দেবে না যাতে কোনও ডেটা থাকে না। অর্ডার ঐ খালি অন্তর পাওয়ার জন্য আমরা ফাংশন ব্যবহার করতে পারেন generate_series

    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 

জেনারেট_সরিজের শেষ প্যারামিটারটি সামঞ্জস্য করে ব্যবধানটি সহজেই পরিবর্তন করা যায়। আমাদের ক্ষেত্রে আমরা '5 মি' ব্যবহার করি তবে এটি আমাদের চাই কোনও অন্তর হতে পারে ।


4
এটি মাইএসকিউএল হলে হত। জেনারেট_সরিজগুলি পোস্টগ্র্রেএসকিউএল ফাংশন বলে মনে হচ্ছে। খুব খারাপ.
আন্দ্রেস

প্রথম ক্যোয়ারী যা কেবলমাত্র উপস্থিত তথ্য কেবল ফলাফল দেয়, এটি উভয় সময়ের মধ্যে 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 তে সঠিকভাবে করছে না
ডেভিডসি

4
যারা কৌতূহলী তাদের জন্য, DIVমাইএসকিউএলে floor()একটি ফ্লোট বিভাগ যা এস এর সাথে নিরাপদ BIGINT
এরিক এল।

4
আমি এটিও চেষ্টা করেছি। এটি প্রতিবার 2 মিনিট বা 3 মিনিটের ব্যবধান এবং আরও 5 মিনিটের বিরতিতে প্রথম রেকর্ড ভুল দেখায়। দ্রষ্টব্য: - আমি সর্বশেষ 15 মিনিটের রেকর্ড পাওয়ার জন্য একটি শর্ত যুক্ত করেছি।
রীতেশ

রাউন্ডের পরিবর্তে একজনকে ট্রুনকেট বা ফ্লোর ব্যবহার করা উচিত কারণ রাউন্ডিং আচরণটি সঠিকভাবে সংজ্ঞায়িত হয় না এবং ব্যবহৃত সি লাইব্রেরির উপর নির্ভর করে। list.mysql.com/mysql/93613
মিঃ লিঃ

28

জন্য postgres , আমি এটা সহজ এবং আরো ব্যবহার করতে সঠিক পাওয়া

তারিখ_তারা

ফাংশন, মত:

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
@ স্মার্টল - এটি উজাড় করা উচিত নয়। মূল প্রশ্নটি মাইএসকিএল-এর জন্য ছিল।
বাগডকম কম

30
আপনি 5এখানে 5 মিনিটের ব্যবধানে কোথায় সেট করবেন ?
ওল্ডগোড

উপরেরগুলির জন্য, যেখানে শর্তটি পরিবর্তন করুন: যেখানে টাইমস্ট্যাম্প> বর্তমান_টাইমস্ট্যাম্প - বিরতি '5 মিনিট'
লূক স্মিথ

4
এই ক্যোয়ারী যা জিজ্ঞাসা করা হয়েছে তা করে বলে মনে হচ্ছে না, প্রশ্ন এখন '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 তে বিভক্ত করতে চলেছেন: এইচএম এবং ডিআইভি 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

... এবং তারপরে ক্লায়েন্ট কোডে আউটপুট futz আপনার পছন্দ মত প্রদর্শিত হবে। অথবা, আপনি যদি পছন্দ করেন তবে পৃথক কলামগুলি পাওয়ার জন্য বর্গাকার কনক্যাট অপারেটরস্ট্যান্ড ব্যবহার করে পুরো তারিখের স্ট্রিং তৈরি করতে পারেন।

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

আপনার এখনও এটি প্রয়োজন কিনা তা নিশ্চিত নয় Not

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

আমি জানতে পেরেছিলাম যে মাইএসকিউএল দিয়ে সম্ভবত সঠিক কোয়েরিটি নিম্নলিখিত:

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))

আপনার প্রশ্নের জন্য একটি ব্যাখ্যা প্রদান করুন।
ড্যানিয়েল ডব্লিউ।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.