Chr*_* G. 1 sql t-sql sql-server aggregate-functions
考虑以下两个表:
key_names
----------------------------------------------
id | name
----------------------------------------------
1 Outside Temperature
2 Inside Temperature
3 Relative Humidity
key_values
----------------------------------------------
id | time | key_id | value
----------------------------------------------
1 2013-06-04 13:20:16.347 1 50
2 2013-06-04 13:20:16.348 2 30
3 2013-06-04 13:20:16.349 3 10
4 2013-06-04 13:20:31.120 1 55
5 2013-06-04 13:20:31.122 2 29
6 2013-06-04 13:20:31.120 3 11
Run Code Online (Sandbox Code Playgroud)
对于3个不同的密钥,值以15秒的间隔写入数据库.我希望能够在1分钟,5分钟,1小时和其他时间间隔取出值.
这就是我现在所用的五分钟间隔:
SELECT time, key_name, value
FROM key_values kv
JOIN key_names kn ON kv.key_id = kn.id
WHERE (key_id = 1 OR key_id = 2 OR key_id = 3)
AND time >= '2013-06-04 12:20:30'
AND time < '2013-06-04 13:20:30'
GROUP BY DATEPART(YEAR, time), DATEPART(MONTH, time), DATEPART(DAY, time),
DATEPART(HOUR, time), (DATEPART(MINUTE, time) / 5), kv.key_id, kn.key_name
ORDER BY kv.time DESC
Run Code Online (Sandbox Code Playgroud)
当然,这个查询会给我以下错误:
列'key_values.time'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中.
但我不想要任何汇总数据!我只想要五分钟间隔的行的实际值.我该如何修复此查询?
预期结果集:(间隔5分钟)
----------------------------------------------------
time | key_id | value
----------------------------------------------------
2013-06-04 13:20:16 1 50
2013-06-04 13:20:16 2 30
2013-06-04 13:20:16 3 10
2013-06-04 13:15:16 1 ...
2013-06-04 13:15:16 2 ...
2013-06-04 13:15:16 3 ...
2013-06-04 13:10:16 1 ...
2013-06-04 13:10:16 2 ...
2013-06-04 13:10:16 3 ...
... ... ...
Run Code Online (Sandbox Code Playgroud)
对于其中一个回答我问题的人:
SELECT time, key_name, value
FROM (
SELECT time, key_name, value, ROW_NUMBER() over (partition by convert(varchar(16), time, 121) order by time desc) as seqnum
FROM key_values kv
JOIN key_names kn ON kn.id = kv.tag_id
WHERE (key_id = 1 OR key_id = 2 )
AND time >= '2013-06-04 12:20:30' AND time < '2013-06-04 13:20:30'
) k
where seqnum = 1;
Its only returning one of the keys..
2013-06-04 12:20:59.577 Outside Temperature 45
2013-06-04 12:21:59.607 Outside Temperature 45
2013-06-04 12:22:59.637 Outside Temperature 45
2013-06-04 12:23:59.687 Outside Temperature 45
2013-06-04 12:24:59.697 Outside Temperature 46
2013-06-04 12:25:59.723 Outside Temperature 46
Run Code Online (Sandbox Code Playgroud)
您希望使用该row_number()函数枚举每个间隔中的值.然后,只取最后一个或第一个 - 取决于你是想要在间隔之前的最后一个还是在它之前的第一个.
以下是1分钟间隔的示例:
select time, key_name, value
from (SELECT time, key_name, value,
ROW_NUMBER() over (partition by key_name, convert(varchar(16), time, 121) order by time desc) as seqnum
FROM key_values kv join
key_names kn
ON kv.key_id = kn.id
) k
where seqnum = 1;
Run Code Online (Sandbox Code Playgroud)
表达式convert(varchar(16), time, 121)是将日期格式化为最接近的分钟(使用截断).
编辑:其他增量.以下示例显示如何在15分钟的跨度内执行此操作:
(partition by key_name, datediff(minute, 0, time)/15 order by . . . )
Run Code Online (Sandbox Code Playgroud)
使用5分钟增量5而不是15依此类推.这是计算自开始时间以来的分钟数(数据库说话).SQL Server执行整数除法,因此除以整数会创建时间跨度的标识符.对于其他单位,可以代替minute用hour,second,day,month,或year.
对于原始查询,我认为这convert()更容易理解.
| 归档时间: |
|
| 查看次数: |
277 次 |
| 最近记录: |