我正在使用Oracle的1个表。我知道我要问的是非常复杂的。我准备提供100分。
我需要了解我的用户在给定范围内每小时的工作时间。
它包含以下字段Out_ID
,OFF_TIME
,ON_TIME
和Users_Affected
查询
SELECT
OUT_ID,
OFF_TIME,
ON_TIME,
USER_AFFECTED
From TableA
where OFF_TIME > '06-02-201 00:00:00' and ON_TIME < '06-02-2014 16:00:00'
order by 2
输出
OUT_ID OFF_TIME ON_TIME USER_AFFECTED
------ ------------------- ------------------- -------------
46791 06-02-2014 00:32:05 06-02-2014 01:15:57 1
46792 06-02-2014 01:32:07 06-02-2014 01:52:51 51
46793 06-02-2014 01:49:40 06-02-2014 01:52:51 10
46794 06-02-2014 03:31:11 06-02-2014 04:31:57 1
46795 06-02-2014 03:51:07 06-02-2014 06:18:52 19
46796 06-02-2014 04:42:44 06-02-2014 05:40:47 1
46809 06-02-2014 06:13:24 06-02-2014 06:23:05 1
46811 06-02-2014 06:44:48 06-02-2014 09:18:59 1
46812 06-02-2014 06:45:55 06-02-2014 06:46:34 1933
46813 06-02-2014 06:57:40 06-02-2014 07:01:41 1
46814 06-02-2014 07:00:14 06-02-2014 07:58:20 1
46815 06-02-2014 07:51:07 06-02-2014 09:03:48 1
46816 06-02-2014 07:59:26 06-02-2014 08:30:13 1
46817 06-02-2014 08:35:09 06-02-2014 10:02:13 1
46818 06-02-2014 08:46:45 06-02-2014 09:28:04 3
46819 06-02-2014 09:01:03 06-02-2014 10:12:47 1
46820 06-02-2014 09:06:09 06-02-2014 10:28:46 23
46821 06-02-2014 09:27:15 06-02-2014 10:55:37 1
46822 06-02-2014 10:15:35 06-02-2014 11:57:48 1
46823 06-02-2014 10:17:39 06-02-2014 10:23:24 4
46824 06-02-2014 10:36:02 06-02-2014 10:44:24 99
46825 06-02-2014 10:39:11 06-02-2014 10:44:24 40
46826 06-02-2014 10:56:46 06-02-2014 11:54:41 1
46827 06-02-2014 11:07:33 06-02-2014 12:08:19 1
46829 06-02-2014 11:22:50 06-02-2014 13:35:36 1
46830 06-02-2014 11:24:56 06-02-2014 11:34:28 1
46831 06-02-2014 11:30:16 06-02-2014 12:15:54 1
46832 06-02-2014 11:32:09 06-02-2014 12:43:55 1
46833 06-02-2014 11:57:44 06-02-2014 12:44:29 1
46834 06-02-2014 12:04:48 06-02-2014 12:54:32 238
46835 06-02-2014 12:04:54 06-02-2014 12:54:32 22
46836 06-02-2014 13:21:39 06-02-2014 13:58:58 1
46837 06-02-2014 13:24:50 06-02-2014 15:41:33 1
46838 06-02-2014 13:26:02 06-02-2014 14:09:57 1
46839 06-02-2014 13:53:23 06-02-2014 14:35:51 1
46840 06-02-2014 13:59:56 06-02-2014 14:02:52 1
46841 06-02-2014 14:04:17 06-02-2014 15:21:43 1
46842 06-02-2014 14:20:52 06-02-2014 15:02:57 4
46843 06-02-2014 14:28:40 06-02-2014 16:15:54 1
46844 06-02-2014 14:36:43 06-02-2014 14:44:38 1
46845 06-02-2014 14:37:26 06-02-2014 15:27:17 1
46847 06-02-2014 15:13:32 06-02-2014 16:04:04 1
46848 06-02-2014 15:23:53 06-02-2014 16:44:25 1
46849 06-02-2014 15:28:14 06-02-2014 15:29:15 1
46850 06-02-2014 15:35:46 06-02-2014 17:41:09 1
输出我想看,我尝试的是。
我做了2个查询。一个用于OUT_ID
OFF_TIME
,第二个用于OUT_ID
ON_TIME
。
查询1
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')
order by OFF_HOUR
按小时计算所有用户的输出。
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.
Querty2 Userback ON
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.
我现在所做的是在excel中进行计算,取每小时的差异。
NUM_CUST_OFF - NUM_CUST_ON时间为06-02-2014 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
答案 0 :(得分:2)
使用分析函数SUM(首先考虑LAG,但不确定它是否可以处理动态字段):
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之间的关系变为FULL JOIN,对T1.TIME_HOURLY的任何引用都被COALESCE(OFF1.OFF_HOUR,ON1.ON_HOUR)替换。