我有一张表格,里面有关于工作的信息:工作类型,开始时间和结束时间。
我想要一份报告,告诉我每小时有多少工作 - 但不是时钟时间,而是距离该组第一份工作时间60分钟的非工作时间(他们是一批工作,所以我确切地知道工作类型不会在时间上重叠。
这样的事情:
num_of_jobs | job_type | hour ----------------------------- 1254 | B | 2011-08-22 13:47 9983 | B | 2011-08-22 14:47 9072 | B | 2011-08-22 15:47 20309 | B | TOTAL 79 | C | 2011-08-22 16:02 105 | C | 2011-08-22 17:02 184 | C | TOTAL 10234 | D | 2011-08-22 17:29 9882 | D | 2011-08-22 18:29 20116 | D | TOTAL
如果可以按小时分组(例如12:00,13:00,14:00),我可以很容易地这样做(非常简化的实际查询版本):
select count(job_id) number_of_jobs, job_type,
case when to_char(end_date,'YYYY-MM-DD HH24') is not null
then to_char(end_date,'YYYY-MM-DD HH24')||':00'
else 'TOTAL'
end Date_and_hour
from my_jobs
where end_date is not null
group by rollup (to_char(end_date,'YYYY-MM-DD HH24')) , job_type
order by to_char(end_date,'YYYY-MM-DD HH24') asc, job_type asc;
除了小时数上的小组,而不是基于job_type的批次中最小的开始时间。
我真的不太确定如何让这个工作。
(使用Oracle 10g)
答案 0 :(得分:2)
在我看来,真正的问题在于找出每行所属的小时组。完成后,您可以将其插入您提供的查询中以获得最终答案。要获得小时组,我们所要做的就是弄清楚自小组最早时间以来已经过了多少小时:
select floor((end_date - min(end_date)
over (partition by job_type))*24)+1 as hour_group
from my_jobs
where end_date is not null
我正在使用trunc
,因为我们只关心整个小时并添加一个,以便我们从一开始计数,而不是零。由于此解决方案使用分析函数,因此您需要在分组之前将其放在子查询中。
稍微玩一下,我最终会得到以下(未经测试的)查询:
SELECT COUNT(job_id) number_of_jobs,
job_type,
min_time + FLOOR((end_date - min_time) * 24) / 24 AS date_and_hour
FROM (SELECT job_id,
job_type,
end_date,
MIN(end_date) OVER (PARTITION BY job_type) AS min_time
FROM my_jobs
WHERE end_date IS NOT NULL)
GROUP BY ROLLUP(min_time + FLOOR((end_date - min_time) * 24) / 24), job_type
ORDER BY hour_group ASC, job_type ASC;
原理与我最初的答案相同,我只是稍微调整一下数学。