【问题标题】:MySQL Group Epoch Timestamp by Every 15 MinutesMySQL 组 Epoch 时间戳每 15 分钟
【发布时间】:2020-10-07 23:21:31
【问题描述】:

我有一个数据库,它以相当高的频率收集一些数据并记录每个条目的时间戳(存储为纪元时间,而不是 mysql 日期时间)。例如

timestamp               rssi    sender
-------------------------------------------
1592353967.171600       -67     9EDA3DBFFE15
1592353967.228000       -67     9EDA3DBFFE15
1592353967.282900       -62     E2ED2569BE2
1592353971.892600       -67     9EDA3DBFFE15
1592353973.962900       -61     2ADE2E4597B2
...

我的目标是能够在 15 分钟的时间间隔内获得所有行的计数,经过研究可以通过 GROUP BY 获得。理想情况下,最终输出应该是这样的

timestamp               count
------------------------------
1592352000 (8:00pm EST)   38    
1592352900 (8:15pm EST)   22
1592353800 (8:30pm EST)   0 <----- Important, must include periods with 0 entries
1592354700 (8:45pm EST)   61
...

我在这里主要遇到两件事: 1.能够在结果中显示时间戳间隔 2.在一个时间段内显示0行的区间

我目前的尝试如下,它在正确的轨道上,因为那里时间段的数据实际上是正确的

 Showing rows 0 - 23 (24 total, Query took 0.0264 seconds.)

SELECT count(*) AS total, MINUTE(FROM_UNIXTIME(timestamp)) AS minute
FROM requests
WHERE timestamp >= 1592352000 AND timestamp < (1592352000 + 3600)  
GROUP BY MINUTE(FROM_UNIXTIME(timestamp))

total   minute  
55  32  
89  33  
64  34  
55  35  
87  36  
82  37  
90  38  
69  39  
74  40  
47  41  
89  42  
53  43  
71  44  
87  45  
72  46  
83  47  
86  48  
83  49  
113 50  
76  51  
77  52  
88  53  
81  54  
28  55  

这个数据是正确的,但是这里没有显示一些时间段(这个小时的前 30 分钟没有数据,因此第一个 minute 条目从 32 开始)。还尝试使用

每 15 分钟获取一次
SELECT count(*) AS total, MINUTE(FROM_UNIXTIME(timestamp)) AS minute
FROM requests
WHERE timestamp >= 1592352000 AND timestamp < (1592352000 + 3600)  
GROUP BY MINUTE(FROM_UNIXTIME(timestamp)) DIV 15

#1055 - Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'wave_master.requests.timestamp' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

任何帮助将不胜感激。

【问题讨论】:

  • 鉴于您提到了表示层,请考虑处理那里的数据显示问题
  • @Strawberry 感谢您的快速回复。我已经考虑过这一点,但问题是数据量很大,在我将其发送到表示层之前对其进行分组是有意义的,因为它将通过 HTTP 发送到 ios 设备进行显示。
  • 哪个版本的 MySQL?
  • 没关系;我更多的是在谈论缺失值。

标签: php mysql lamp


【解决方案1】:

您可以使用“数字”表生成一小时 (0-3) 内的 15 分钟周期,然后将 LEFT JOIN 按 15 分钟周期分组,然后使用 COALESCE 替换 @ 987654324@ 值为 0:

SELECT periods.period * 900 + 1592352000 AS timestamp,
       FROM_UNIXTIME(periods.period * 900 + 1592352000) AS time,
       COALESCE(counts.total, 0) AS total
FROM (
  SELECT 0 period
  UNION ALL SELECT 1 
  UNION ALL SELECT 2
  UNION ALL SELECT 3
) periods
LEFT JOIN (
  SELECT (timestamp - 1592352000) DIV 900 AS period,
         COUNT(*) AS total
  FROM requests
  WHERE timestamp >= 1592352000 AND timestamp < 1592352000 + 3600
  GROUP BY period
) counts ON counts.period = periods.period

输出(对于您问题中的数据以及其他几个值):

timestamp   time                    total
1592352000  2020-06-17 00:00:00     1
1592352900  2020-06-17 00:15:00     1
1592353800  2020-06-17 00:30:00     5
1592354700  2020-06-17 00:45:00     0

Demo on dbfiddle

【讨论】:

  • 非常感谢您的回答!效果很好!如果我想从 15 分钟更改间隔,我假设我可以添加/删除期间。
  • @chrislawrence 我很高兴能帮上忙。如果要更改间隔,只需更改900 值和periods 表中值的数量即可;例如,对于 10 分钟的间隔,您将使用 600 并将 UNION ALL SELECT 4 UNION ALL SELECT 5 添加到 periods 表中。如果不清楚,请告诉我。
猜你喜欢
  • 2021-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-17
  • 2013-10-08
相关资源
最近更新 更多