【问题标题】:MySQL - SQL to skip intervals e.g. records every 5 minutesMySQL - SQL 跳过间隔,例如每5分钟记录一次
【发布时间】:2014-08-09 17:43:10
【问题描述】:

我需要什么。一条 SQL 语句将查找一条记录,即最新的,然后查找比该记录的时间戳晚 5 分钟的下一条记录,并重复直到达到限制。时间戳是unix时间。因此,获取最新记录然后减去 5 分钟,获取该记录并重复。 5分钟就是一个例子。它实际上是一个从秒到小时的变量。 我可以很容易地用 Perl、Ruby 或 Bash 编写一些程序来执行一个循环,里面有一个可以工作的选择,但我希望有一种可能更快的纯 SQL 方式。任何帮助表示赞赏。

在下方添加了更多信息。

下面显示了数据库表中记录的一个非常小的片段。基本上数据间隔 20 秒插入。我希望能够根据通过 CGI 脚本传递的变量以不同的时间间隔选择一条记录,以及我希望总共返回多少条记录。

> select * from Sensor1 order by ts desc limit 5; +------------+-------------+----------+ | ts |温度 |湿度 | +------------+-------------+----------+ | 1407612981 | 75.91 | 56.5 | | 1407612961 | 75.92 | 56.4 | | 1407612941 | 75.92 | 56.5 | | 1407612921 | 75.91 | 56.4 | | 1407612901 | 75.91 | 56.4 | +------------+-------------+----------+

举个例子,我想要最新的记录,然后是 5 分钟后的一个,然后是 5 分钟后返回到 CGI 脚本传递的其他变量的一个。 下面将是基于需要 5 次迭代中相隔最接近 5 分钟的记录的示例输出。

+------------+-------------+----------+ | ts |温度 |湿度 | +------------+-------------+----------+ | 1407612681 | 75.92 | 56.4 | | 1407612381 | 75.92 | 56.4 | | 1407612081 | 75.90 | 56.3 | | 1407611781 | 75.91 | 56.4 | | 1407611481 | 75.90 | 56.4 | +------------+-------------+----------+

所以我可以用一个简单的 bash 脚本来完成上述工作。见下文。

#!/bin/bash
increment=5     # How many records we want
interval=300    # The number of seconds between each returned result
tc1=1
while [ $tc1 -lt $increment ]
do
  time=$(($time-$interval))    # This line makes sure our next select query is 300 seconds behind
  record=`echo "select * from Sensor${sensor} where ts >= ${time} order by ts asc limit 1;" | mysql -u env -penv -h localhost dc_temp | sed 's/\t/|/g' | grep -v "ts|temperature|humidity"`
  echo "Debug: ${record}"
  time=`echo $record | cut -d'|' -f1`  # Get the time from output.
  tc1=$((tc1+1))   # Add 1 to our temporary count to end the while loop when we reach how many records they want
done

所以上面的脚本给了我想要和控制的输出。但我担心大量的选择会减慢速度。我希望以每条记录之间的不同间隔提取 24 小时、1 周、1 个月、1 年的数据。基本上24小时,每5分钟拉一次。对于 1 周的拉取,可能会在一小时内记录几条记录等。数据全部发送到 RGraph 以创建历史温度和湿度的折线图。

【问题讨论】:

  • 欢迎来到 StackOverflow!我担心你的问题有点不清楚,你最好用一些样本数据和期望的结果来编辑你的问题。下一张唱片是什么?它是该区间中最古老的记录吗?如果没有这样的记录呢?那么你想要一个 NULL,... 好的部分是:它可以做到 :-) 坏的部分:我不知道它会有多有效。

标签: mysql sql intervals


【解决方案1】:

你能试试运行下面的代码吗:

CREATE TABLE dbo.TimeTable(value INT,time DATETIME);
GO
SET NOCOUNT ON;
GO
INSERT dbo.TimeTable(value, time) SELECT 1, DATEADD(MINUTE, -7, GETDATE());
INSERT dbo.TimeTable(value, time) SELECT 2, DATEADD(MINUTE, -6, GETDATE());
INSERT dbo.TimeTable(value, time) SELECT 3, DATEADD(MINUTE, -5, GETDATE());
INSERT dbo.TimeTable(value, time) SELECT 4, DATEADD(MINUTE, -4, GETDATE());
INSERT dbo.TimeTable(value, time) SELECT 5, DATEADD(MINUTE, -3, GETDATE());
INSERT dbo.TimeTable(value, time) SELECT 6, DATEADD(MINUTE, -2, GETDATE());
INSERT dbo.TimeTable(value, time) SELECT 7, DATEADD(MINUTE, -1, GETDATE());
INSERT dbo.TimeTable(value, time) SELECT 8, GETDATE();

;WITH myTbl AS
(
SELECT 
time, value, RANK() OVER (PARTITION BY (DATEDIFF(Mi,0, time)/5) ORDER BY time desc) RK
FROM TimeTable
)

SELECT * FROM myTbl
WHERE RK <= 1
ORDER BY time DESC

DROP TABLE TimeTable

这将返回每隔 5 分钟的最新记录。

【讨论】:

  • 感谢您的快速回复,但是我无法使建议的代码在 MySQL 中工作。从我对 Microsoft SQL 的一点经验来看,它看起来更适合 Microsoft SQL。既然我有时间提取一些示例数据,我已经在我的描述中添加了更多信息。我将不胜感激任何其他想法。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-16
  • 2012-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多