用数字波动计算总和

时间:2013-08-15 23:34:52

标签: sql-server

我正在计算水流量,遇到了一种情况,需要帮助。

Date/Time  Account   Read
---------  --------  -----
04:00.0    16887084  38665
03:30.0    16887084  38652 **<< Reverse flow**
03:00.0    16887084  38660
02:30.0    16887084  38656

我需要计算用水量(如Read Col所示),但由于逆流,03:30的样品回滚8加仑,下一个样品增加了13加仑。如何计算真实用水量?我尝试了以下内容,但声明基本上使用数字范围作为用法的表示:

SELECT  serial AS Account,
    max(READ)- min(READ) AS GalsTotal,

    FROM dbo.Database 
WHERE (dbf_DT > DATEADD(HH, -24, getdate())) 

非常感谢任何帮助......

2 个答案:

答案 0 :(得分:0)

一种方法是获取该期间内最后一次阅读的日期和时间,以及该期间(或该期间开始前的最后一次阅读)的首次阅读日期和时间,然后使用该方法检索行。

SELECT s.serial AS Account
     , MAX(lr.READ) - MIN(fr.READ) AS GalsTotal
  FROM (SELECT d.serial
             , MIN(d.dbf_DT) AS first_read_dt
             , MAX(d.dbf_DT) AS last_read_dt
          FROM dbo.Database d
         WHERE d.dbf_DT > DATEADD(HH, -24, GETDATE()
         GROUP BY d.serial
       ) s
  JOIN dbo.Database fr
    ON fr.serial = s.serial 
   AND fr.dbf_DT = s.first_read_dt
  JOIN dbo.Database lr
    ON lr.serial = s.serial 
   AND lr.dbf_DT = s.last_read_dt
 GROUP
    BY s.serial

(如果保证dbf_Dt对于给定的序列是唯一的,则不需要MIN和MAX聚合。如果(serial,dbf_DT)上有唯一约束,则可以删除MIN和MAX,它们在那里仅在有多个行匹配first_read_dt或last_read_dt的情况下进行区分。

另一种方法是使用SQL Server中可用的分析函数来完成同样的事情。

答案 1 :(得分:0)

如果您只想总结每次阅读之间的差异,那么您可以使用公用表表达式和窗口函数(SQL Server 2012)或Row_Number()来完成。这两个都导致了9加仑的答案。有关工作示例,请参阅SQL Fiddle

WITH WaterFlow AS (
SELECT 
 serial,
 a.amount_read - LAG(a.amount_read) OVER(PARTITION BY a.serial ORDER BY a.date_read ASC) AS gallons             
FROM useage a
WHERE date_read > DATEADD(HH, -24, getdate())  
)
SELECT 
 serial as account,
 SUM(gallons) AS gallons
FROM WaterFlow
GROUP BY
 serial
;

以上使用LAG窗口函数,它允许您查看上一行,但仅适用于SQL Server 2012.

WITH WaterFlow AS (
 SELECT 
  serial,
  ROW_NUMBER() OVER (PARTITION BY serial
                           ORDER BY date_read ASC) rn,
  amount_read
 FROM useage
 WHERE date_read > DATEADD(HH, -24, getdate())
)
SELECT 
 a.serial as account,
 SUM(b.amount_read - a.amount_read) as gallons
FROM WaterFlow a
LEFT JOIN WaterFlow b ON 
 a.serial= b.serial
 AND b.rn = a.rn +1  
GROUP BY
 a.serial
;

以上使用行号并进行自联接以获取前一行,并且应该适用于SQL Server 2005及更高版本。