其他时间之间的返回时间

时间:2017-06-26 14:44:33

标签: oracle oracle11g

我有两张表AVAILAVAIL_TIMESAVAIL包含avail_id,avail_date,open_flag。 AVAIL_TIMES包含avail_times_id,Avail_id,Start_Time,End_time。所有日期和时间字段都输入为DATE

如果在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解决方案。

2 个答案:

答案 0 :(得分:1)

我不确定你想如何输入感兴趣的日期(我使用了一个绑定变量,作为一个字符串传入 - 但这可能不适合你,也许你想加入你的另一个表等等) - 或您想要的确切输出。在任何情况下,下面的查询都演示了从输入中获得此类输出所需的代码的“核心”。

<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

答案 1 :(得分:0)

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

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;