如何计算日期时间范围内的n个平均值?

时间:2013-08-27 17:39:59

标签: sql sql-server

我有一个应用程序,它从几个(现在48个)不同的数据点每隔15秒对数据进行采样。这些数据点在表中由两个不同的外键(MeasurementTypeId和GeneratorId),一个样本值(Value)和一个日期时间(MeasurementDate)表示。

所以,表格看起来像这样(我只包括10行,只有几个不同的外键组合)

+------+-------------------+-------------+-------+------------------------+
|  ID  | MeasurementTypeId | GeneratorId | Value | MeasurementDate        |
+------+-------------------+-------------+-------+------------------------+
|    1 |       PSI         |     SG-52   |  0.19 |   2013-08-27 09:19:30  |
|    2 |       PH          |     SG-52   |  6.39 |   2013-08-27 09:19:30  |
|    3 |       DEG         |     SG-52   | 90.85 |   2013-08-27 09:19:30  |
|    4 |       PSI         |     PT-14   |  0.33 |   2013-08-27 09:19:30  |
|    5 |       PH          |     PT-14   |  6.41 |   2013-08-27 09:19:30  |
|    6 |       DEG         |     PT-14   | 89.20 |   2013-08-27 09:19:30  |
|    7 |       PSI         |     SG-52   |  0.20 |   2013-08-27 09:19:45  |
|    8 |       PH          |     SG-52   |  6.37 |   2013-08-27 09:19:45  |
|    9 |       DEG         |     SG-52   | 90.84 |   2013-08-27 09:19:45  |
|   10 |       PSI         |     PT-14   |  0.34 |   2013-08-27 09:19:45  |
+------+-------------------+-------------+-------+------------------------+

我正在寻找创建一个存储过程,该存储过程可以返回日期时间范围内的间隔的平均值(按外键分组)。但是,我不想定义间隔,而是将其留给用户调用存储过程。

我希望存储过程采用

的参数
@numberOfIntervals int,
@startDateRange datetime,
@endDateRange datetime

并将startDateRange和endDateRange的日期值除以numberOfIntervals,以确定进行平均值的间隔。

例如,如果使用3,'2013-08-26 00:00:00','2013-08-27 00:00:00'调用该过程

结果将是每组3条记录的组合,其值等于8小时间隔的平均值(为简洁起见,仅包括10条结果......实际结果将包括18条)

+-------------------+-------------+-------+------------------------+
| MeasurementTypeId | GeneratorId | Value | MeasurementDate        |
+-------------------+-------------+-------+------------------------+
|       PSI         |     SG-52   |  0.20 |   2013-08-26 08:00:00  |
|       PH          |     SG-52   |  7.11 |   2013-08-26 08:00:00  |
|       DEG         |     SG-52   | 90.02 |   2013-08-26 08:00:00  |
|       PSI         |     PT-14   |  0.44 |   2013-08-26 08:00:00  |
|       PH          |     PT-14   |  6.98 |   2013-08-26 08:00:00  |
|       DEG         |     PT-14   | 90.31 |   2013-08-26 08:00:00  |
|       PSI         |     SG-52   |  0.21 |   2013-08-26 16:00:00  |
|       PH          |     SG-52   |  7.12 |   2013-08-26 16:00:00  |
|       DEG         |     SG-52   | 90.01 |   2013-08-26 16:00:00  |
|       PSI         |     PT-14   |  0.44 |   2013-08-26 16:00:00  |
+-------------------+-------------+-------+------------------------+

我已经做了一些计算移动平均线的工作,但那是针对特定时间范围和特定数量的间隔。有了这个,我希望用户能够选择日期范围和指定数量的间隔并绘制结果图。

1 个答案:

答案 0 :(得分:1)

您可以创建一个CTE来获取按

分组的间隔
DECLARE @numberOfIntervals INT = 3
DECLARE @startDateRange DATETIME = '2013-08-27'
DECLARE @endDateRange DATETIME = '2013-08-28'

--

DECLARE @range INT = DATEDIFF(HH, @startDateRange, @endDateRange) / @numberOfIntervals

;WITH calendar AS
(
  SELECT @startDateRange StartDate, DATEADD(HH, @range, @startDateRange) EndDate
  UNION ALL
  SELECT DATEADD(HH, @range, StartDate), DATEADD(HH, @range, EndDate)
  FROM calendar
  WHERE DATEADD(HH, @range, StartDate) < @endDateRange
)

SELECT MeasurementTypeId, 
       GeneratorId, 
       StartDate AS MeasurementDateStart,
       AVG(Value) AverageValue
FROM (
    SELECT d.*, c.StartDate
    FROM data d
    JOIN calendar c
      ON d.MeasurementDate >= c.StartDate
     AND d.MeasurementDate < c.EndDate
) sub
GROUP BY MeasurementTypeId, GeneratorId, StartDate

demo

您可能想要添加的内容是处理@numberOfIntervals不能很好地划分,如果@numberOfIntervals大于24等,则添加分钟而不是小时。