我希望得到一些帮助来编写一些我自己没有成功的SQL。
我有一张包含数据的表格:
ID StartDate EndDate 1 01/01/2000 04:30 AM 01/02/2000 06:15 AM 2 01/03/2000 06:10 AM 01/03/2000 07:00 AM
我需要得到以下内容:
Hour24 Minutes 04 30 05 60 06 65 07 60
换句话说,按小时分割日期范围。然后按小时汇总每个范围。 我的数据库是Oracle 11G R2,我担心由于情况我无法使用PL / SQL。
非常感谢你的帮助!
答案 0 :(得分:0)
基本上,要解决此问题,您只需要一个数字列表。
with nums as (
select 0.0 as n from dual
union all
select n + 1
from nums
where n < 100
)
select trunc(t.startdate + n * 1/ 24, 'hh'),
sum((case when trunc(t.startdate + n * 1/24, 'hh') = trunc(t.startdate, 'hh')
then 60 - extract(minute from startdate)
else 0
end) +
(case when trunc(t.startdate + n * 1/24, 'hh') > trunc(t.startdate, 'hh') and
trunc(t.startdate + n * 1/24, 'hh') < trunc(t.enddate, 'hh')
then 60
else 0
end) +
(case when trunc(t.startdate + n * 1/24, 'hh') = trunc(t.enddate, 'hh')
then extract(minute from enddate)
else 0
end)
) as minutes
from table t join
nums n
where trunc(t.startdate + n * 1/24, 'hh') <= t.enddate;
这适用于日期长达100小时的差异。您可以根据需要调整100
。您甚至可以使用子查询来获得正确的最大值。
有些技巧可以简化逻辑。我认为上述逻辑是最清楚的。它循环工作时间。如果比较的小时是第一个小时,请使用60分钟。如果是最后一个,请使用分钟。否则,请使用60。
答案 1 :(得分:0)
作为第一步,您需要一个包含24行的表。不好的例子:
从all_objects中选择rownum rnum,其中rownum&lt; 25
然后你将该表加入到你的表中,条件是rnum小时在startdate和enddate之间
在select和from之间你会把rnum和一个公式用来计算该特定记录中的分钟数和rnum小时
然后你将该查询包装在另一个具有GROUP BY构造的查询中。
答案 2 :(得分:0)
如果您的日期时间范围可以超过一天,正如您的示例数据所示,那么它们可能会占用超过60分钟的一小时。例如,我们有一个荒谬的过程,需要48个小时才能完成,因此在检查时,只需说出小时6,基于24小时计数器的查询将返回60,而实际上他们可能需要返回120。
with hours as (
select trunc(sysdate, 'hh') - ((rownum - 1) / 24) as testhour
from dual connect by rownum <= (trunc(sysdate, 'hh') - (trunc(sysdate, 'mm') - (1 / 24))) * 24
)
select
to_char(h.testhour, 'hh24') as Hour24,
round(sum((least(t.stopdatetime, h.testhour + (1/24)) - greatest(t.startdatetime, h.testhour)) * 1440)) Minutes
from
datetimes t,
hours h
where
t.stopdatetime >= trunc(sysdate, 'mm')
and (
h.testhour between t.startdatetime and t.stopdatetime
or h.testhour = trunc(t.startdatetime, 'hh')
)
group by
to_char(h.testhour, 'hh24')
order by 1
;
此查询应处理这些情况,但在其当前表单中运行需要更长时间;它会返回每个小时的日期时间,从本月的第一个小时到当前小时。