运行总计和读数重置

时间:2016-09-20 16:48:47

标签: sql oracle

我有一张表,可存储我们机器的计时器读数。读数存储为运行总计,因此每月发生几次的每次读取都是累计总数。

事情是,有时仪表会断裂,并且它们会被更换。在这种情况下,读数类型从ACTUAL变为RESET,读数重置为新值,打破了运行总量。

我有一个查询获得每月抄表的最大值,因此我可以获得最后一次读数,因此我可以与Tableau中的另一个表一起进行可视化,将维护成本与运营时间进行比较。

我目前的查询是这样的:

select assetnum,
  to_date(to_char(readingdate, 'MM/')||'01/'||to_char(readingdate, 'YYYY'), 'MM/DD/YYYY') reading_date,
  max(reading) month_reading
from meterreading
group by assetnum, to_char(readingdate, 'MM/')||'01/'||to_char(readingdate, 'YYYY')
order by to_date(to_char(readingdate, 'MM/')||'01/'||to_char(readingdate, 'YYYY'), 'MM/DD/YYYY')

这将返回如下表格:

Assetnum  readingdate  month_reading
8021      01/01/2016   3500
8021      02/01/2016   4200
8021      03/01/2016   5100
8021      04/01/2016   5900
8021      05/01/2016   6300
8021      06/01/2016    200      <-- meter was reset
8021      07/01/2016    350
8021      08/01/2016    403

所以,我设想了两种解决方法:

1)如果仪表重置,我找到了将最后一个读数添加到当前读数的方法,或者

2)删除积累,并在每次阅读时只获得当前月份读数,因此重置是不重要的

我更倾向于选项2,但我想听听你的意见。

BTW,正如我上面提到的,源表有一个名为readingtype的字段,如果是常规读数则表示ACTUAL,如果更换了计时表,则表示RESET。

感谢您的帮助

UPDATE !!!

我想要达成的目标是:

Assetnum  readingdate  month_reading
8021      01/01/2016   3500
8021      02/01/2016   4200
8021      03/01/2016   5100
8021      04/01/2016   5900
8021      05/01/2016   6300
8021      06/01/2016   6500      <-- add the current to the previous
8021      07/01/2016   6850
8021      08/01/2016   7253

或者这个:

Assetnum  readingdate  month_reading
8021      01/01/2016   3500
8021      02/01/2016   700      <-- get the monthly value, not accumulated
8021      03/01/2016   900
8021      04/01/2016   800
8021      05/01/2016   400
8021      06/01/2016    200      <-- meter was reset, so no matter
8021      07/01/2016    350
8021      08/01/2016    403

希望现在更清楚了

1 个答案:

答案 0 :(得分:1)

假设RESET读取类型值仅附加到重置后的第一个完整月份,则第二种方法很容易实现。要获得“每月使用”,您将使用

case readingtype when 'RESET' then month_reading
                 else month_reading - lag(month_reading) 
                                      over (partition by assetnum order by readingdate)
end as monthly_usage

在SELECT子句中。

在任何情况下,即使没有readingtype的帮助,您也可以重写case表达式来测试month_reading < lag(month_reading) over ...(它是RESET的标记);如果它已经存在,请利用readingtype

增加:显然,每个资产的第一个月读数都没有标记为“重置”(这使得它与所有其他“第一”读数不同)。这会导致问题,因为对于每个资产的第一次读取,滞后(...)为NULL(没有先前的读数),因此差异也是NULL。

这可以修复。不需要减去lag(...) over (...),而是需要减去

nvl( lag(...) over (...), 0 )

即减去滞后值UNLESS它为null,在这种情况下减去0。