2012-02-17 39 views
-3

数据库:SQL Server 2008 R2的如何在连续的日期范围计算的平均运行

表结构

  location, date,      temperature 

      NY  2011-12-06 21:07:00 -05:00 20 
      NY  2011-12-06 21:08:00 -05:00 21 
      NY  2011-12-06 21:09:00 -05:00 22 
      NY  2011-12-06 21:10:00 -05:00 23 
      NY  2011-12-06 21:11:00 -05:00 24 <- Minute breaks here 
      NY  2011-12-06 21:22:00 -05:00 27 
      NY  2011-12-06 21:23:00 -05:00 25 
      NY  2011-12-06 21:24:00 -05:00 26 
      NY  2011-12-06 21:25:00 -05:00 25 
      NY  2011-12-06 21:26:00 -05:00 26 
      NY  2011-12-06 21:27:00 -05:00 24 <- Minute breaks here(NY ends) 
      MA  2011-12-06 21:07:00 -05:00 21 
      MA  2011-12-06 21:08:00 -05:00 22 
      MA  2011-12-06 21:09:00 -05:00 24 
      MA  2011-12-06 21:10:00 -05:00 23 
      MA  2011-12-06 21:11:00 -05:00 22 <- Minute breaks here 
      MA  2011-12-06 21:22:00 -05:00 22 
      MA  2011-12-06 21:23:00 -05:00 25 
      MA  2011-12-06 21:24:00 -05:00 26 
      MA  2011-12-06 21:25:00 -05:00 24 
      MA  2011-12-06 21:26:00 -05:00 25 
      MA  2011-12-06 21:27:00 -05:00 29 

要求:该表有一个多列名为running_average_temp 。在日期的连续分钟内计算温度的运行平均值的最佳方法是什么? (即每个位置的连续分钟读数都是一组数据,需要为该组中的每一行计算运行平均值)该表具有更多位置。

(发布要求:该表每小时得到一次输入,新进入的行可能会持续现有行的分钟数,也可能是一组新的读数,计算最佳方式是什么每小时出现一组新的运行平均值。)

+5

您是否尝试过任何东西,除了要求我们做所有的工作适合你? – JNK 2012-02-17 19:15:07

+2

如果您要给我们提供数据,您至少应该提供表创建脚本:p – jcolebrand 2012-02-17 19:36:23

+0

该计算无法通​​过单个SQL查询实现吗?这就是我正在寻找的。 – 2012-02-17 20:13:45

回答

0

下面是一个答案,其中一些边界案例已添加到数据集中。

DECLARE @temps TABLE 
    (
    location varchar(2) NOT NULL, 
    date datetime NOT NULL, 
    temperature tinyint NOT NULL 
    ) 

INSERT INTO @temps (location, date, temperature) VALUES ('NY', '2011-12-06 21:07:00',20) 
INSERT INTO @temps (location, date, temperature) VALUES ('NY', '2011-12-06 21:08:00',21) 
INSERT INTO @temps (location, date, temperature) VALUES ('NY', '2011-12-06 21:09:00',22) 
INSERT INTO @temps (location, date, temperature) VALUES ('NY', '2011-12-06 21:10:00',23) 
INSERT INTO @temps (location, date, temperature) VALUES ('NY', '2011-12-06 21:11:00',24) --<- Minute breaks here 
INSERT INTO @temps (location, date, temperature) VALUES ('NY', '2011-12-06 21:22:00',27) 
INSERT INTO @temps (location, date, temperature) VALUES ('NY', '2011-12-06 21:23:00',25) 
INSERT INTO @temps (location, date, temperature) VALUES ('NY', '2011-12-06 21:24:00',26) 
INSERT INTO @temps (location, date, temperature) VALUES ('NY', '2011-12-06 21:25:00',25) 
INSERT INTO @temps (location, date, temperature) VALUES ('NY', '2011-12-06 21:26:00',26) 
INSERT INTO @temps (location, date, temperature) VALUES ('NY', '2011-12-06 21:27:00',24) --<- Minute breaks here 
INSERT INTO @temps (location, date, temperature) VALUES ('NY', '2011-12-06 22:00:00',28) --<- Minute breaks here 
INSERT INTO @temps (location, date, temperature) VALUES ('MA', '2011-12-06 21:07:00',21) 
INSERT INTO @temps (location, date, temperature) VALUES ('MA', '2011-12-06 21:08:00',22) 
INSERT INTO @temps (location, date, temperature) VALUES ('MA', '2011-12-06 21:09:00',24) 
INSERT INTO @temps (location, date, temperature) VALUES ('MA', '2011-12-06 21:10:00',23) 
INSERT INTO @temps (location, date, temperature) VALUES ('MA', '2011-12-06 21:11:00',22) --<- Minute breaks here 
INSERT INTO @temps (location, date, temperature) VALUES ('MA', '2011-12-06 21:22:00',22) 
INSERT INTO @temps (location, date, temperature) VALUES ('MA', '2011-12-06 21:23:00',25) 
INSERT INTO @temps (location, date, temperature) VALUES ('MA', '2011-12-06 21:24:00',26) 
INSERT INTO @temps (location, date, temperature) VALUES ('MA', '2011-12-06 21:25:00',24) 
INSERT INTO @temps (location, date, temperature) VALUES ('MA', '2011-12-06 21:26:00',25) 
INSERT INTO @temps (location, date, temperature) VALUES ('MA', '2011-12-06 21:27:00',29) 
INSERT INTO @temps (location, date, temperature) VALUES ('MA', '2011-12-06 22:00:00',32)--<- Minute breaks here 

;WITH TempSets (RowNumber, location, date, temperature, nextminutetemperature, previousminutetemperature) 
AS 
(
SELECT 
    ROW_NUMBER() OVER (ORDER BY T.location ASC, T.date ASC) AS RowNumber, 
    T.location, 
    T.date, 
    T.temperature, 
    T1.temperature AS nextminutetemperature, 
    T2.temperature AS previousminutetemperature 
FROM 
    @temps T 
    LEFT JOIN @temps T1 ON 
     T1.location = T.location 
     AND T1.date = DATEADD(minute, +1, T.date) 
    LEFT JOIN @temps T2 ON 
     T2.location = T.location 
     AND T2.date = DATEADD(minute, -1, T.date) 
) 

SELECT 
    Result.location, 
    MIN(Result.date) AS starttime, 
    MAX(Result.date) AS endtime, 
    COUNT(Result.groupidentifier) AS numberofreadings, 
    AVG(Result.temperature) AS averagetemperature 
FROM 
(
SELECT 
    (
    CASE 
     WHEN 
      TempSets.previousminutetemperature IS NULL 
      AND TempSets.nextminutetemperature IS NULL 
      THEN TempSets.rownumber 
     ELSE 
      (
      SELECT 
       MIN(GroupNumber.rownumber) 
      FROM 
       TempSets AS GroupNumber 
      WHERE 
       GroupNumber.location = TempSets.location 
       AND GroupNumber.rownumber >= TempSets.rownumber 
       AND GroupNumber.nextminutetemperature IS NULL 
      ) 
    END 
    ) AS groupidentifier, 
    TempSets.rownumber, 
    TempSets.location, 
    TempSets.date, 
    TempSets.temperature, 
    TempSets.nextminutetemperature, 
    TempSets.previousminutetemperature 
FROM 
    TempSets 
) AS Result 
GROUP BY 
    Result.groupidentifier, 
    Result.location 
ORDER BY 
    Result.location ASC, 
    MIN(Result.date) ASC 

结果:

location starttime    endtime     numberofreadings averagetemperature 
-------- ----------------------- ----------------------- ---------------- ------------------ 
MA  2011-12-06 21:07:00.000 2011-12-06 21:11:00.000 5    22 
MA  2011-12-06 21:22:00.000 2011-12-06 21:27:00.000 6    25 
MA  2011-12-06 22:00:00.000 2011-12-06 22:00:00.000 1    32 
NY  2011-12-06 21:07:00.000 2011-12-06 21:11:00.000 5    22 
NY  2011-12-06 21:22:00.000 2011-12-06 21:27:00.000 6    25 
NY  2011-12-06 22:00:00.000 2011-12-06 22:00:00.000 1    28 
+0

我在Tsql中编写了这个程序。这有助于了解如何使用SQL来解决问题。感谢您采用这种方法,我可以尝试将其发展为运行平均计算。 – 2012-02-17 20:46:21

+0

欢迎来到计算器。 – 2012-02-17 21:04:23

+0

另一种方法是找到所有边界情况,其中没有行的时间少于1分钟,或者没有行的时间多于1分钟,并通过使用边界位置/日期作为下限/上限进行解决的子集。只是思考的食物。 – 2012-02-17 23:12:34