每隔 30 分钟计算一次数据库中的重复记录
Posted
技术标签:
【中文标题】每隔 30 分钟计算一次数据库中的重复记录【英文标题】:Count recurring records on data base every 30 minutes interval 【发布时间】:2013-02-28 16:02:20 【问题描述】:我在下面需要一些帮助
我有表“数据”获取存储在其上的数据,如下所示
+------------+----------+-----------
| regdate | regtime | items
+------------+----------+-----------
| 2013-03-02 | 09:12:03 | item1
| 2013-03-02 | 10:12:05 | item1
| 2013-03-02 | 15:12:07 | item2
| 2013-03-02 | 20:12:09 | item3
| 2013-03-02 | 21:12:11 | item4
| 2013-03-02 | 22:12:14 | item3
10 道菜等可以在一天中的不同时间从 09:00 到 23:00 上桌
我还有另一个表 "ItemsPerInterval",如下所示
+------------+-------------+-------------+-------------+-------------+
| regdate | reginterval | item1 | item2 | item3 |
+------------+-------------+-------------+-------------+-------------+
| 2013-03-01 | 09:00:00 | 0 | 0 | 0 |
+------------+-------------+-------------+-------------+-------------+
以 30 分钟 为基础增加的时间间隔如 09:00 , 09:30 , 10:00, 10:30 ... 直到 23:00
我想做的是在表上插入数据ItemsPerInterval 包括表“数据”(item1、item2、item3、.... item10)上项目的重复计数 并按时间间隔(09:00:00、09:30:00、10:00:00、10:30:00、.... 23:00:00)存储它们,以便每个间隔 - 例如 - 09:00:00 将具有从 09:00:00 开始在 Data 表中注册的所有项目的重复计数直到 09:29:59 直到 23:00:00
编辑**1
因此,最终必须在 ItemsPerInterval 表上注册所有以下间隔,并保存间隔时间窗口中已报告的 10 个项目中每个项目的计数
09:00:00
09:30:00
10:00:00
10:30:00
11:00:00
11:30:00
12:00:00
12:30:00
13:00:00
13:30:00
and so on .....
.
.
.
22:00:00
22:30:00
23:00:00
/编辑**1
我阅读了一些关于例程/程序的资料,但我不知道其中的区别,也不知道如何使用它来实现上述内容。
我正在使用 软件:mysql 软件版本:5.5.24 使用 php。
感谢您的支持
谢谢
【问题讨论】:
09:00-23:00 范围之外是否有regtime
,如果有,应该如何处理?
将结果存储在新表中没有多大意义,因为您始终可以使用将按间隔选择和分组项目的查询从表数据中检索此数据。
而你大约半小时可能类似于FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(regtime)/1800)*1800);
@Wrikken 是的,由于人为错误,一些项目将在此范围之外注册,但我稍后会添加另一个表来跟踪范围外的项目。所以现在这个考虑超出范围的项目被忽略
@AhmedElGamilI 如果你想要不存在的间隔(没有发生任何事情),数据必须来自 somewhere 以获得LEFT JOIN
,所以你;可能必须使用09:00,09:30....22:30,23:00
序列创建一个虚拟表。
【参考方案1】:
你可以使用这个查询:
SELECT
regdate,
SEC_TO_TIME(TRUNCATE(TIME_TO_SEC(regtime)/(60*30),0)*(60*30)) reginterval,
COUNT(CASE WHEN items='item1' THEN 1 END) item1,
COUNT(CASE WHEN items='item2' THEN 1 END) item2,
COUNT(CASE WHEN items='item3' THEN 1 END) item3,
COUNT(CASE WHEN items='item4' THEN 1 END) item4
FROM Data
GROUP BY
regdate,
reginterval
如果您需要将结果行插入到新表中,只需在开头添加此行:
INSERT INTO ItemsPerInterval (regdate, reginterval, item1, item2, item3, item4)
SELECT ...
编辑
如果您还想显示所有区间,即使它们没有值,我认为您能做的最好的事情就是有一个表 Intervals
包含您需要的所有区间:
CREATE TABLE Intervals (
reginterval time
);
INSERT INTO Intervals VALUES
('09:00:00'),
('09:30:00'),
('10:00:00'),
...
此查询返回所有间隔,并结合表中存在的所有日期:
SELECT Dates.regdate, Intervals.reginterval
FROM
(SELECT DISTINCT regdate FROM Data) Dates,
Intervals
这个查询返回你需要的行:
SELECT
di.regdate,
di.reginterval,
COUNT(CASE WHEN Data.items='item1' THEN 1 END) item1,
COUNT(CASE WHEN Data.items='item2' THEN 1 END) item2,
COUNT(CASE WHEN Data.items='item3' THEN 1 END) item3,
COUNT(CASE WHEN Data.items='item4' THEN 1 END) item4
FROM (
SELECT Dates.regdate, Intervals.reginterval
FROM (SELECT DISTINCT regdate FROM Data) Dates,
Intervals
) di
LEFT JOIN Data
ON di.regdate=Data.regdate
AND di.reginterval=SEC_TO_TIME(TRUNCATE(TIME_TO_SEC(Data.regtime)/(60*30),0)*(60*30))
GROUP BY
regdate,
reginterval;
请看小提琴here。
这是如何工作的
这里的想法是使用TIME_TO_SEC函数将包含时间的字段regtime
转换为从一天开始的秒数:
TIME_TO_SEC(regtime)
然后我们将这个数字除以 60*30,即 30 分钟内的秒数,只保留整数部分:
TRUNCATE(number_of_seconds/(60*30), 0)
然后我们将整数部分乘回到60*30得到秒数,四舍五入为60*30秒(30分钟)。
使用SEC_TO_TIME,我们将秒数转换回时间字段。
【讨论】:
非常感谢您的回答,但假设在 13:00:00 间隔内没有注册任何内容,我仍然希望所有数据都显示为 0 -请参阅主题编辑 @AhmedElGamil 我更新了我的答案,当间隔内没有注册任何内容时,它将显示全部 0 非常感谢它正在工作。这为我节省了很多其他查询可以完成的运行时间。 aahm ,, 好更新,而现场测试计数不正确。例如 | 2013-03-02 | 09:12:03 |项目1 | 2013-03-02 | 09:28:05 | item1 计数应该反映在第一个间隔 2 上,但它显示 1 一个 9 和一个 9:30 @AhmedElGamil 你可能需要 TRUNCATE(..,0) 而不是 ROUND(),我再次更新以上是关于每隔 30 分钟计算一次数据库中的重复记录的主要内容,如果未能解决你的问题,请参考以下文章