我正在计算水流量,遇到了一种情况,需要帮助。
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()))
非常感谢任何帮助......
答案 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及更高版本。