Oracle 其他时间之间的返回时间

Oracle 其他时间之间的返回时间,oracle,oracle11g,Oracle,Oracle11g,我有两张空桌和空桌时间。AVAIL包含AVAIL\u id、AVAIL\u日期、open\u标志。可用时间包含可用时间id、可用id、开始时间、结束时间。所有日期和时间字段都键入为日期 如果在avail open_flag(可用打开标志)列中标记了日期,则表示该设施在该日期打开,但其打开时间在avail_times(可用打开时间)中列出。对于特定的一天,可以有多个时间范围 我需要返回当天未开放的时间列表 例如一天的许多 每日开放时间: Start_time: 08:00 End_time 10:

我有两张空桌和空桌时间。AVAIL包含AVAIL\u id、AVAIL\u日期、open\u标志。可用时间包含可用时间id、可用id、开始时间、结束时间。所有日期和时间字段都键入为日期

如果在avail open_flag(可用打开标志)列中标记了日期,则表示该设施在该日期打开,但其打开时间在avail_times(可用打开时间)中列出。对于特定的一天,可以有多个时间范围

我需要返回当天未开放的时间列表

例如一天的许多

每日开放时间:

Start_time: 08:00 End_time 10:00
Start_time: 12:00 End_time 14:00
Start_time: 15:00 End_time 17:00
我希望它能返回如下内容:

00:00 - 07:59
10:01 - 11:59
14:01 - 14:59
17:01 - 23:59

我想我可以用一个临时表和一些plsql逻辑来解决这个问题,但理想情况下,这将是一个纯sql解决方案。

我不太确定您想如何输入感兴趣的日期,我使用了一个绑定变量,作为字符串传入-但这可能不是您的正确方法,也许您想加入到另一个表中,等等-或您想要的确切输出。在任何情况下,下面的查询都演示了从输入实现这种输出所需的代码核心

alter session set nls_date_format='mm/dd/yyyy hh24:mi';

with
     avail_times ( start_time, end_time ) as (
       select to_date('06/20/2017 08:00'), to_date('06/20/2017 10:00') from dual union all
       select to_date('06/20/2017 12:00'), to_date('06/20/2017 14:00') from dual union all
       select to_date('06/20/2017 15:00'), to_date('06/20/2017 17:00') from dual
     )
select   trunc(min(start_time)) as start_time, min(start_time) as end_time
  from   avail_times
  where  trunc(start_time) = to_date(:input_date, 'mm/dd/yyyy')
union all
select   end_time, 
         lead(start_time, 1, trunc(start_time) + 1) over (order by start_time)
  from   avail_times
  where  trunc(end_time) = trunc(start_time)
order by start_time
;

START_TIME        END_TIME
----------------  ----------------
06/20/2017 00:00  06/20/2017 08:00
06/20/2017 10:00  06/20/2017 12:00
06/20/2017 14:00  06/20/2017 15:00
06/20/2017 17:00  06/21/2017 00:00

另一种方法。希望这有帮助

SELECT ID,
  START_TME,
  END_TM,
  DIFF_TM
FROM
 --Not part of SQL just to simulate the table data
  (WITH TMP AS
  (SELECT 1 ID,
    TO_DATE('06/27/2017 00:00','mm/dd/yyyy hh24:mi') START_TME,
    TO_DATE('06/27/2017 08:00','mm/dd/yyyy hh24:mi') END_TM
  FROM DUAL
  UNION ALL
  SELECT 1 ID,
    TO_DATE('06/27/2017 10:00','mm/dd/yyyy hh24:mi') START_TME,
    TO_DATE('06/27/2017 15:00','mm/dd/yyyy hh24:mi') END_TM
  FROM DUAL
  UNION ALL
  SELECT 1 ID,
    TO_DATE('06/27/2017 16:00','mm/dd/yyyy hh24:mi') START_TME,
    TO_DATE('06/27/2017 17:00','mm/dd/yyyy hh24:mi') END_TM
  FROM DUAL
  UNION ALL
  SELECT 1 id,
    to_date('06/27/2017 17:00','mm/dd/yyyy hh24:mi') start_tme,
    TO_DATE('06/27/2017 18:00','mm/dd/yyyy hh24:mi') END_TM
  FROM DUAL
  )
  --SQL start from here
SELECT TMP.*,
  LEAD(START_TME) OVER(PARTITION BY ID ORDER BY 1 DESC) next_st_tm,
  LEAD(END_TM) OVER(PARTITION BY ID ORDER BY 1 DESC) NEXT_EN_TM,
  EXTRACT( HOUR FROM TO_TIMESTAMP(LEAD(START_TME) OVER(PARTITION BY ID ORDER BY 1 DESC),'MM/DD/YYYY HH24:MI'))- EXTRACT(HOUR FROM TO_TIMESTAMP(end_tm,'MM/DD/YYYY HH24:MI')) DIFF_TM
FROM TMP
ORDER BY 1 ,
  2
  )
WHERE DIFF_TM <> 0;

这两张桌子的确切结构是什么?结构是指列名及其数据类型。如果某些栏目与你的问题无关,你可以删掉它们。例如,表中是否有两列,开始时间和结束时间?他们是瓦查尔2可怕的选择!数据类型,或者他们是完美的日期!数据类型?那么:在第二个表中,为什么希望第一行是从00:00到07:59,而不是从08:00?或者下一个10:01开始,而不是10:00开始?这很奇怪,也不合逻辑。编辑的意思是所有的日期和时间字段都键入为日期。我想让他们提前一分钟,以便有人仍然可以安排8:00的约会。在我看来,这并不是不合逻辑的。如果在08:00开门,为什么我要它一直开到08:00?如果这使解更容易,那么好吧,但我必须在别处解释。时间是连续的,而不是像整数1,2,3,4这样的离散步骤。。。。如果一个时间间隔是从00:00到07:59,下一个时间间隔是从08:00到10:00,那么07:59:30落在哪里?8点前30秒。在几乎所有情况下,对于时间间隔,您最好匹配一个间隔的结束和下一个间隔的开始。例如:在一个简单的计算中,您将显示在一天开始的7小时59分钟内空间不可用。这是错误的:8小时内不可用,7小时59分钟内不可用。另一个问题:可用时间能否跨越午夜22:00到次日04:00,或者甚至几天?或者,在这种情况下,间隔是否已经细分为每个日历日的间隔?不,该ID的所有开始和结束时间都将在同一天。非常酷。非常感谢。这并不完全是我所需要的,但它会让我达到目的。