Oracle Hourly Report在给定日期范围内按小时减去两个字段

Oracle Hourly Report在给定日期范围内按小时减去两个字段,oracle,datetime,oracle11g,Oracle,Datetime,Oracle11g,我正在使用Oracle的1个表。我知道我的问题很复杂。我准备给你100分 我需要了解我的用户在给定范围内每小时是如何外出的 它有以下字段Out\u ID、OFF\u TIME、ON\u TIME和受影响的用户 质疑 我希望看到的输出,我尝试的是 我提出了两个问题。一个用于OUT\u ID OFF\u TIME,另一个用于OUT\u ID ON\u TIME 问题1 Querty2用户返回 select trunc(ON_TIME,'HH') as ON_HOUR, sum(USE

我正在使用Oracle的1个表。我知道我的问题很复杂。我准备给你100分

我需要了解我的用户在给定范围内每小时是如何外出的

它有以下字段Out\u ID、OFF\u TIME、ON\u TIME和受影响的用户

质疑

我希望看到的输出,我尝试的是

我提出了两个问题。一个用于OUT\u ID OFF\u TIME,另一个用于OUT\u ID ON\u TIME

问题1

Querty2用户返回

select trunc(ON_TIME,'HH') as ON_HOUR, 
       sum(USER_AFFECTED) AS Num_Cust_ON
  From TableA
 where OFF_TIME > '06-02-2014 00:00:00' 
   and ON_TIME < '06-02-2014 16:00:00' 
 group by trunc(ON_TIME,'HH') 
 order by ON_HOUR
我现在要做的是在excel中计算每小时的差值

NUM_CUST_OFF-NUM_CUST_ON于2014年2月6日00:00:00如果有结转,则添加到下一个小时,并再次计算差额

所以我在excel中得到了以下信息,我得到了以下信息

TIME_HOURLY     USER_STILL_AFFECTED
-------------   -------------------
6/2/2014 0:00   1
6/2/2014 1:00   0
6/2/2014 3:00   20
6/2/2014 4:00   20
6/2/2014 5:00   19
6/2/2014 6:00   2
6/2/2014 7:00   3
6/2/2014 8:00   6
6/2/2014 9:00   26
6/2/2014 10:00  2
6/2/2014 11:00  5
6/2/2014 12:00  1
6/2/2014 13:00  4
6/2/2014 14:00  7
6/2/2014 15:00  0

使用分析函数求和,首先考虑滞后,但不确定是否能在飞行场上处理:

SELECT T1.TIME_HOURLY,
    SUM(NVL(OFF1.Num_Cust_OFF, 0)-NVL(ON1.Num_Cust_ON,0)) 
          OVER (ORDER BY T1.TIME_HOURLY) AS USER_STILL_AFFECTED
FROM (
    SELECT trunc(OFF_TIME,'HH') as TIME_HOURLY From tableA
    UNION -- this will get distinct result
    SELECT trunc(ON_TIME,'HH') as TIME_HOURLY From tableA
) T1
LEFT JOIN (
    SELECT trunc(OFF_TIME,'HH') as OFF_HOUR, 
        sum(USER_AFFECTED) AS Num_Cust_OFF
    From tableA
    where OFF_TIME > '06-02-2014 00:00:00' 
        and ON_TIME < '06-02-2014 16:00:00' 
    group by trunc(OFF_TIME,'HH') 
) OFF1 ON T1.TIME_HOURLY = OFF1.OFF_HOUR
LEFT JOIN (
    select trunc(ON_TIME,'HH') as ON_HOUR, 
        sum(USER_AFFECTED) AS Num_Cust_ON
    From TableA
    where OFF_TIME > '06-02-2014 00:00:00' 
        and ON_TIME < '06-02-2014 16:00:00' 
    group by trunc(ON_TIME,'HH') 
) ON1 ON T1.TIME_HOURLY = ON1.ON_HOUR
ORDER BY T1.TIME_HOURLY
以上是未经测试和优化,但应该给正确的解决方案提示


可能的优化:子查询T1可能会被删除,OFF1和ON1之间的关系变成完全连接,对T1.TIME\u HOUR的任何引用都会被COALESCEOFF1.OFF\u HOUR、ON1.ON\u HOUR替换。

我可能只是明显地忽略了这一点,但你能更好地解释发生了什么吗?我不明白为什么3:00和4:00都是=20。Np:,你必须减去OFF-ON=results从1:00小时减去1:00小时,从2:00小时减去2:00小时..你必须匹配并减去。你得到的结果是,你必须把这一点延续到下一个小时……最后一个小时应该是0。非常感谢,我真的很喜欢你的方法,非常有用的提示和想法。ON1 ON T1.TIME\u HOURLY-ON1.ON\u HOUR应该是=intead of-。没有发现那个打字错误。修正。我有问题,我已经做了两个单独的查询。我现在正试图加入他们。我已经有一个很长的查询,但我需要帮助添加两个查询的用户仍然受影响我怎么做?在不知道详细要求的情况下,我会说使用连接,将用户仍然受影响的逻辑包装到子查询中,就像T1、OFF1和ON1一样。若长查询已经预先使用了tableA,那个么为了获得更好的性能,可能会建议进行重写—不过,在重写方面我帮不了你们多少忙。
OFF_HOUR            NUM_CUST_OFF
------------------- ------------
06-02-2014 00:00:00            1
06-02-2014 01:00:00           61
06-02-2014 03:00:00           20
06-02-2014 04:00:00            1
06-02-2014 06:00:00         1936
06-02-2014 07:00:00            3
06-02-2014 08:00:00            4
06-02-2014 09:00:00           25
06-02-2014 10:00:00          145
06-02-2014 11:00:00            6
06-02-2014 12:00:00          260
06-02-2014 13:00:00            5
06-02-2014 14:00:00            7
06-02-2014 15:00:00            1

14 rows selected.
select trunc(ON_TIME,'HH') as ON_HOUR, 
       sum(USER_AFFECTED) AS Num_Cust_ON
  From TableA
 where OFF_TIME > '06-02-2014 00:00:00' 
   and ON_TIME < '06-02-2014 16:00:00' 
 group by trunc(ON_TIME,'HH') 
 order by ON_HOUR
ON_HOUR             NUM_CUST_ON
------------------- -----------
06-02-2014 01:00:00          62
06-02-2014 04:00:00           1
06-02-2014 05:00:00           1
06-02-2014 06:00:00        1953
06-02-2014 07:00:00           2
06-02-2014 08:00:00           1
06-02-2014 09:00:00           5
06-02-2014 10:00:00         169
06-02-2014 11:00:00           3
06-02-2014 12:00:00         264
06-02-2014 13:00:00           2
06-02-2014 14:00:00           4
06-02-2014 15:00:00           8

13 rows selected.
TIME_HOURLY     USER_STILL_AFFECTED
-------------   -------------------
6/2/2014 0:00   1
6/2/2014 1:00   0
6/2/2014 3:00   20
6/2/2014 4:00   20
6/2/2014 5:00   19
6/2/2014 6:00   2
6/2/2014 7:00   3
6/2/2014 8:00   6
6/2/2014 9:00   26
6/2/2014 10:00  2
6/2/2014 11:00  5
6/2/2014 12:00  1
6/2/2014 13:00  4
6/2/2014 14:00  7
6/2/2014 15:00  0
SELECT T1.TIME_HOURLY,
    SUM(NVL(OFF1.Num_Cust_OFF, 0)-NVL(ON1.Num_Cust_ON,0)) 
          OVER (ORDER BY T1.TIME_HOURLY) AS USER_STILL_AFFECTED
FROM (
    SELECT trunc(OFF_TIME,'HH') as TIME_HOURLY From tableA
    UNION -- this will get distinct result
    SELECT trunc(ON_TIME,'HH') as TIME_HOURLY From tableA
) T1
LEFT JOIN (
    SELECT trunc(OFF_TIME,'HH') as OFF_HOUR, 
        sum(USER_AFFECTED) AS Num_Cust_OFF
    From tableA
    where OFF_TIME > '06-02-2014 00:00:00' 
        and ON_TIME < '06-02-2014 16:00:00' 
    group by trunc(OFF_TIME,'HH') 
) OFF1 ON T1.TIME_HOURLY = OFF1.OFF_HOUR
LEFT JOIN (
    select trunc(ON_TIME,'HH') as ON_HOUR, 
        sum(USER_AFFECTED) AS Num_Cust_ON
    From TableA
    where OFF_TIME > '06-02-2014 00:00:00' 
        and ON_TIME < '06-02-2014 16:00:00' 
    group by trunc(ON_TIME,'HH') 
) ON1 ON T1.TIME_HOURLY = ON1.ON_HOUR
ORDER BY T1.TIME_HOURLY