检查日期范围与其他日期范围

时间:2014-03-17 05:39:55

标签: sql oracle

我的表格Distractions包含以下列:
id startTime endTime(可能为空)

另外,我有两个参数,它是句号。 pstartpend
我必须找到所有分心的时间和计数时间 例如,我们有:
Distractions

 `id`      `startTime`                   `endTime`  
   1     01.01.2014 00:00             03.01.2014 00:00
   2     25.03.2014 00:00             02.04.2014 00:00
   3     27.03.2014 00:00                   null

列包含时间,但不要使用它们   期间为pstart = 01.01.2014pend = 31.03.2014
例如,上面的结果是相同的:

  • for id = 1 - 72小时
  • 代表id = 2 - 168小时(从25日到7日的7天) 31 - 期末)
  • for id = 3 - 120小时(从27到31的5天 - 分心未完成,因此选择结束时段)

总和等于360。

我的代码:

select 
     sum ((ds."endTime" - ds."startTime")*24) as hoursCount
from "Distractions" ds
--where ds."startTime" >= :pstart and ds."endTime" <= :pend
-- I don't know how to create where condition properly.

1 个答案:

答案 0 :(得分:2)

您必须处理日期范围超出输入范围并且还将starttime和endtime视为null的情况。 此where子句应仅保留有效数据范围。我已将null startime替换为最早的日期,将null endtime替换为日期 远在将来。

where coalesce(endtime,date'9999-12-31')   >= :pstart
  and coalesce(starttime,date'0000-01-01') <= :pend

一旦过滤了记录,您需要调整日期值,以便在输入之前开始的任何内容:pstart向前移动到:pstart, 以及之后结束的任何事情:pend被移回:pend。减去这两个应该给出你正在寻找的价值。但是有一个问题。以来 时间是00:00:00,当你减去日期时,它会错过一整天。所以,加1吧。

SQL Fiddle

Oracle 11g R2架构设置

create table myt(
id number,
starttime date,
endtime date
);

insert into myt values( 1 ,date'2014-01-01', date'2014-01-03');
insert into myt values( 2 ,date'2014-03-25', date'2014-04-02');
insert into myt values( 3 ,date'2014-03-27', null);
insert into myt values( 4 ,null, date'2013-04-02');
insert into myt values( 5 ,date'2015-03-25', date'2015-04-02');
insert into myt values( 6 ,date'2013-12-25', date'2014-04-09');
insert into myt values( 7 ,date'2013-12-26', date'2014-01-09');

查询1

select id,
       case when coalesce(starttime,date'0000-01-01') < date'2014-01-01'
            then date'2014-01-01'
            else starttime
       end adj_starttime,
       case when coalesce(endtime,date'9999-12-31') > date'2014-03-31'
            then date'2014-03-31'
            else endtime
       end adj_endtime,
       (case when coalesce(endtime,date'9999-12-31') > date'2014-03-31'
            then date'2014-03-31'
            else endtime
       end -
       case when coalesce(starttime,date'0000-01-01') < date'2014-01-01'
            then date'2014-01-01'
            else starttime
       end
       + 1) * 24 hoursCount
from myt
where coalesce(endtime,date'9999-12-31') >= date'2014-01-01'
and coalesce(starttime,date'0000-01-01') <= date'2014-03-31'
order by 1

<强> Results

| ID |                  ADJ_STARTTIME |                    ADJ_ENDTIME | HOURSCOUNT |
|----|--------------------------------|--------------------------------|------------|
|  1 | January, 01 2014 00:00:00+0000 | January, 03 2014 00:00:00+0000 |         72 |
|  2 |   March, 25 2014 00:00:00+0000 |   March, 31 2014 00:00:00+0000 |        168 |
|  3 |   March, 27 2014 00:00:00+0000 |   March, 31 2014 00:00:00+0000 |        120 |
|  6 | January, 01 2014 00:00:00+0000 |   March, 31 2014 00:00:00+0000 |       2160 |
|  7 | January, 01 2014 00:00:00+0000 | January, 09 2014 00:00:00+0000 |        216 |