我试图将一些记录分为5分钟,15分钟,30分钟和60分钟:
SELECT AVG(value) as "AvgValue",
sample_date/(5*60) as "TimeFive"
FROM DATA
WHERE id = 123 AND sample_date >= 3/21/2012
我想运行几个查询,每个查询将我的平均值分组为所需的时间增量。所以5分钟的查询将返回如下结果:
AvgValue TimeFive
6.90 1995-01-01 00:05:00
7.15 1995-01-01 00:10:00
8.25 1995-01-01 00:15:00
30分钟的查询将产生以下结果:
AvgValue TimeThirty
6.95 1995-01-01 00:30:00
7.40 1995-01-01 01:00:00
datetime
列格式为yyyy-mm-dd hh:mm:ss
我收到了datetime
列的隐式转换错误。非常感谢任何帮助!
答案 0 :(得分:17)
使用
datediff(minute, '1990-01-01T00:00:00', yourDatetime)
将为您提供自1990-1-1以来的分钟数(您可以使用所需的基准日期)。
然后你可以除以5,15,30或60,并按此除法的结果分组。 我已经将它评估为整数除法,因此您将得到一个可用于分组的整数。
即
group by datediff(minute, '1990-01-01T00:00:00', yourDatetime) /5
更新由于原始问题已编辑为要求在分组后以日期时间格式显示数据,因此我添加了这个简单的查询,该查询将执行OP所需的内容:
-- This convert the period to date-time format
SELECT
-- note the 5, the "minute", and the starting point to convert the
-- period back to original time
DATEADD(minute, AP.FiveMinutesPeriod * 5, '2010-01-01T00:00:00') AS Period,
AP.AvgValue
FROM
-- this groups by the period and gets the average
(SELECT
P.FiveMinutesPeriod,
AVG(P.Value) AS AvgValue
FROM
-- This calculates the period (five minutes in this instance)
(SELECT
-- note the division by 5 and the "minute" to build the 5 minute periods
-- the '2010-01-01T00:00:00' is the starting point for the periods
datediff(minute, '2010-01-01T00:00:00', T.Time)/5 AS FiveMinutesPeriod,
T.Value
FROM Test T) AS P
GROUP BY P.FiveMinutesPeriod) AP
注意:为了清楚起见,我将其分为3个子查询。你应该从里到外阅读。当然,它可以写成单个紧凑的查询
注意:如果您更改期间和开始日期时间,您可以获得所需的任何时间间隔,例如从某一天开始的几周或任何您需要的时间
如果要为此查询生成测试数据,请使用以下命令:
CREATE TABLE Test
( Id INT IDENTITY PRIMARY KEY,
Time DATETIME,
Value FLOAT)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:00:22', 10)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:03:22', 10)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:04:45', 10)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:07:21', 20)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:10:25', 30)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:11:22', 30)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:14:47', 30)
执行查询的结果是:
Period AvgValue
2012-03-22 00:00:00.000 10
2012-03-22 00:05:00.000 20
2012-03-22 00:10:00.000 30
答案 1 :(得分:6)
所以,如果您使用Google搜索,但您需要在mysql中执行此操作,这是我的情况:
在MySQL中你可以做到
GROUP BY
CONCAT(
DATE_FORMAT(`timestamp`,'%m-%d-%Y %H:'),
FLOOR(DATE_FORMAT(`timestamp`,'%i')/5)*5
)
答案 2 :(得分:6)
在@ JotaBe的答案(我无法评论 - 否则我会)的基础上,您也可以尝试这样的不需要子查询的东西。
SELECT
AVG(value) AS 'AvgValue',
-- Add the rounded seconds back onto epoch to get rounded time
DATEADD(
MINUTE,
(DATEDIFF(MINUTE, '1990-01-01T00:00:00', your_date) / 30) * 30,
'1990-01-01T00:00:00'
) AS 'TimeThirty'
FROM YourTable
-- WHERE your_date > some max lookback period
GROUP BY
(DATEDIFF(MINUTE, '1990-01-01T00:00:00', your_date) / 30)
此更改删除临时表和子查询。它使用相同的核心逻辑以30分钟的间隔进行分组,但是当作为结果的一部分呈现数据时,我只是反转间隔计算以获得舍入的日期&时间。
答案 3 :(得分:0)
这将有助于你想要的
替换 dt
- 您的日期时间 c
- 调用字段 astro_transit1
- 您的表 300 引用 5 分钟,因此每次添加 300 以增加时间间隔
SELECT FROM_UNIXTIME( 300 * ROUND( UNIX_TIMESTAMP( r.dt ) /300 ) ) AS 5datetime, ( SELECT r.c FROM astro_transit1 ra WHERE ra.dt = r.dt ORDER BY ra.dt DESC LIMIT 1 ) AS first_val FROM astro_transit1 r GROUP BY UNIX_TIMESTAMP( r.dt ) DIV 300 LIMIT 0 , 30