Sql 返回结果的平均值

Sql 返回结果的平均值,sql,.net,sql-server,Sql,.net,Sql Server,我们有一个系统,每小时存储1000个来自各种传感器的读数。这些值将被发送到.net图表模块中。这是可行的,但当你查看几天的数据时,基本上有10到数千个结果被输入到图表中,并且处理它们的速度很慢。作为一个快速解决方案,我将其设置为将所有结果分组并平均到一个小时桶中,方法是将日期列分解为小时(去掉分钟和秒)。这工作快得多,但我希望它变得更好。以下是当前(庞大的)查询: 这可以返回几千个结果。它似乎仍然没有有效的图表模块,可能只有300像素宽,试图绘制基本上会重叠的1000点 我的问题是:有没有一种方

我们有一个系统,每小时存储1000个来自各种传感器的读数。这些值将被发送到.net图表模块中。这是可行的,但当你查看几天的数据时,基本上有10到数千个结果被输入到图表中,并且处理它们的速度很慢。作为一个快速解决方案,我将其设置为将所有结果分组并平均到一个小时桶中,方法是将日期列分解为小时(去掉分钟和秒)。这工作快得多,但我希望它变得更好。以下是当前(庞大的)查询:

这可以返回几千个结果。它似乎仍然没有有效的图表模块,可能只有300像素宽,试图绘制基本上会重叠的1000点

我的问题是:有没有一种方法可以告诉SQL只返回300个结果,并使其平均值和日期列?粗略地说,比如“从传感器读数中按日期排序,仅选择300平均值作为值,平均值(日期)作为日期”


谢谢

有两种方法可以按一定数量的行过滤结果。在Select语句中,只需在开头的顶部(300)添加即可限制行数。如果你想使用数学百分比,那么你可以使用最高(2)百分比。或者,可以使用offset和fetch在结果之间进行过滤


对于查询构造,是否可以不对from语句使用派生表,并直接从传感器读数准备好?您可以对主select语句中的列使用avg函数。如果您有来自SensorReads的行的示例输出,这将很有帮助。从传感器读数中选择顶部(5)*

这将起作用-它根据读数数量将范围分成偶数段:

DECLARE @Partitions INT = 300;

WITH AllValues AS
(  SELECT Value,Date,RowNum = ROW_NUMBER() over(ORDER BY Date asc)
   FROM SensorReadings WHERE (SensorID='15')
)
SELECT AverageValue = AVG(Value),
       AverageTime = DATEADD(second,AVG(CAST(datediff(second,'1/1/2000',Date) as BIGINT)),'1/1/2000')
FROM AllValues
GROUP BY RowNum / @Partitions
ORDER BY RowNum / @Partitions

请注意,您不能取datetime的平均值;但是你可以计算自给定时间以来的平均秒数。

感谢上面的马克让我找到了正确的方向。这是我要使用的最后一个SQL。我首先需要确定行的总数,以获得适当的次数来划分行数。这使得网站性能有了巨大的提高

Declare @Partitions int
select    @Partitions=  count(value)/300 +1
from SensorReadings
WHERE     (SensorID = '31') and date>'4/1/2018';
WITH AllValues as
(
SELECT     Value, Date, RowNum = ROW_NUMBER() OVER (ORDER BY Date 
ASC)/@Partitions
FROM         SensorReadings
WHERE     (SensorID = '31') and date>'4/1/2018'
)
SELECT AverageValue = AVG(Value),
   AverageTime = DATEADD(second,AVG(CAST(datediff(second,'1/1/2000',Date) as 
BIGINT)),'1/1/2000')
FROM AllValues
GROUP BY RowNum 
ORDER BY RowNum 

可以使用TOP选择最近的值。如果最新的值位于表的底部,则可能需要按ID ASC或DESC进行排序,以获取表顶部的最新数据。遗憾的是,我目前还没有安装MSSQL来测试它。谢谢,这已经足够让我找到正确的方向了。我将发布我的最终解决方案,我将发布。
Declare @Partitions int
select    @Partitions=  count(value)/300 +1
from SensorReadings
WHERE     (SensorID = '31') and date>'4/1/2018';
WITH AllValues as
(
SELECT     Value, Date, RowNum = ROW_NUMBER() OVER (ORDER BY Date 
ASC)/@Partitions
FROM         SensorReadings
WHERE     (SensorID = '31') and date>'4/1/2018'
)
SELECT AverageValue = AVG(Value),
   AverageTime = DATEADD(second,AVG(CAST(datediff(second,'1/1/2000',Date) as 
BIGINT)),'1/1/2000')
FROM AllValues
GROUP BY RowNum 
ORDER BY RowNum