检查日期范围是否在WW内

时间:2019-07-11 12:58:46

标签: sql oracle

我对比较日期范围有疑问。 我有一张桌子,上面放着一台机器的状态日志。状态可以是0或1。此外,我还有机器状态更改开始和结束的日期

START_DATE | END_DATE | STATE

例如:

     START_DATE     |       END_DATE        | STATE
2019-05-28 07:12:43   2019-05-29 09:12:43       1
2019-05-29 09:12:43   2019-06-01 08:12:43       0
2019-06-11 10:12:43   2019-06-12 16:12:43       1
2019-06-12 16:12:43   2019-06-12 17:12:43       0

我想报告一个遍历每个工作周(工作周)的报告,并检查该工作周的平均状态。

我的问题是,状态更改可能在WW22上发生,并在WW24上结束,所以当我按BY分组时,在WW23上没有任何值,因为WW23上没有开始或结束状态。但是在WW23上,该计算机的状态为0,因为它在WW22上开始并且在WW24上结束,但是一直以来该状态都是0。

看来我无法使用GROUP BY WW来解决它。 如果WW23没有记录,我可能需要检查START_DATE和END_DATE。添加类似的内容:

CASE WHEN WW BETWEEN START_DATE AND END_DATE THEN...

但是我不确定在不使用GROUP BY的情况下如何在WW上循环播放。

我使用SQL ORACLE

谢谢。

1 个答案:

答案 0 :(得分:1)

我希望我理解正确。如果您向我们显示了您的查询,并告诉我们您如何计算平均状态以及这些周的来源,那将是很好的。无论如何,这里的查询会生成2019年的所有星期,并与您的log合并。

select to_char(wsd, 'iw') week, wsd, start_date, end_date, state
  from (
    select trunc(date '2019-01-01', 'iw') + level * 7 - 7 wsd
      from dual 
      connect by trunc(date '2019-01-01', 'iw') + level * 7 <= date '2020-01-01')
  left join log on wsd < end_date and start_date < wsd + 7

有趣的是这个范围:

week  week_start_date  log_start            log_end              state
21    2019-05-20
22    2019-05-27       2019-05-28 07:12:43  2019-05-29 09:12:43  1
22    2019-05-27       2019-05-29 09:12:43  2019-06-01 08:12:43  0
23    2019-06-03
24    2019-06-10       2019-06-11 10:12:43  2019-06-12 16:12:43  1
24    2019-06-10       2019-06-12 16:12:43  2019-06-12 17:12:43  0
25    2019-06-17

我不知道您如何计算第22周和第24周的平均状态。也许它是减去时间的加权平均值,也许是其他时间。但这并不重要,因为您在第23周有遗漏state的行。 如果这意味着先前的值对本周有效,请使用:

nvl(state, lag(state) over (order by wsd))

coalesce(state, lag(state) over (order by wsd), 0)

当您想将0作为默认值时,我们也错过了上周。如果缺少两个星期,请将ignore nulls添加到lag

然后您可以按周对数据进行分组并计算平均值。

dbfiddle demo