【问题标题】:Running total and reading reset运行总计和读数重置
【发布时间】:2016-09-20 16:48:47
【问题描述】:

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

问题是,有时仪表会中断,并且会被替换。在这种情况下,读数类型会从 ACTUAL 更改为 RESET,并且读数会重置为新值,从而打破运行总计。

我有一个查询,获取每月抄表的 MAX,所以我可以得到最后的读数,所以我可以加入 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,但我想听听您的意见。

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

感谢您的帮助

更新!!!

我想要实现的是:

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

希望现在更清晰了

【问题讨论】:

  • 您要解决什么问题?你想要什么结果?
  • 检查更新。希望现在更加清晰
  • 我假设基表将保持不变(您不是在尝试更新“基本数据”),并且您正在寻找的是一个查询 - 或一个视图 - 将显示“正确" 总计或只是每月增量?在您的基表中,哪些行被标记为“RESET” - 只是第一次(第一个月)有重置,还是接下来的所有月份?此外,如果仪表在月中重置会发生什么 - 该月显示的总数将低于应有的值,而 RESET 月将显示更多,这在商业上可行吗?
  • 正确。我只需要一个查询,所以我可以将它与另一个查询结合起来进行可视化。标有 RESET 的行只是该系列的第一个。随后的读数被标记为 ACTUAL,除非稍后有另一个重置,这也会发生。也许不是在同一个月,而是在以后。

标签: sql oracle


【解决方案1】:

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

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 &lt; lag(month_reading) over ...(这是RESET 的标记);如果readingtype 已经存在,请务必利用它。

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

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

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

即减去滞后值,除非它为空,在这种情况下减去 0。

【讨论】:

  • 好的,差不多了。现在缺少对每项资产的第一次阅读。有没有办法在读取新资产编号时识别第一条记录?
  • 呵呵,这是一个逻辑缺陷……第一次读数应始终标记为 RESET,即使它是新资产的第一次读数。这很容易解决,我会添加到我的答案中。
  • 好的,我进行了更改,现在我相信第一行的工作正常。虽然,我在数据中得到了一些奇怪的峰值。我不知道那是什么,真的。顺便说一句,我停止使用读数类型,因为我发现了一些重置仪表的记录,但读数类型是实际的。所以它不能被信任。
  • 这是个问题,因为您不能总是依靠每月读数低于前一个读数来提醒您进行重置。确实,如果您在 6 月下旬进行了 RESET,那么当月的读数为 200(例如),然后在 7 月初再次进行 RESET,而 7 月的读数为 600,该怎么办?仅通过比较值,您不会知道这是连续几个月的第二次 RESET;您会认为 7 月的正确用法是 400。我认为没有技术(数据库)答案 - 这是一个业务问题。
  • 此外,在 RESET 时间可能会出现 DOWNspike;如果读数在 6 月 28 日重新开始,那么 6 月份的读数将非常低。不确定是什么导致了 UPspikes;它们可能只是糟糕的读数。如果 readingtype 不可靠,为什么要假设其余数据是可靠的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-09
  • 2018-01-25
  • 1970-01-01
  • 1970-01-01
  • 2015-12-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多