【问题标题】:how can i find the gaps between overlapping or non overlapping date ranges in one day? [pl/sql]如何在一天内找到重叠或不重叠日期范围之间的差距? [PL/SQL]
【发布时间】:2022-12-04 16:30:27
【问题描述】:

我有一张表格,显示发行人调用该服务时的日期和时间。我想写一个查询来显示在特定日期特定发行人的请求没有涵盖 24 小时。如果有人可以指导我,我将不胜感激。我是 pl sql 的初学者 mht_issuer_revoked_call](https://i.stack.imgur.com/JkLsJ.png)

我尝试按 issuerid 分区并按开始日期排序,并使用滞后时间将开始日期和结束日期与以前的记录进行比较,并添加新的开始和结束日期,但我想我无法通过这种方式得到答案。

select r.*,
        case
          when r.startdate > lag(r.enddate) over(partition by r.issuerid order by r.startdate) then r.startdate
          else min(r.startdate) over(partition by r.issuerid order by r.startdate)
        end startdate_new,
        case
          when lag(r.enddate) over(partition by r.issuerid order by r.startdate) is null then r.enddate
          when r.enddate <= lag(r.enddate) over(partition by r.issuerid order by r.startdate) then lag(r.enddate) over(partition by r.issuerid order by r.startdate)
          when r.enddate > lag(r.enddate) over(partition by r.issuerid order by r.startdate)  then r.enddate
        end enddate_new
  from mht_issuer_revoked_call r

【问题讨论】:

    标签: plsql


    【解决方案1】:

    不太确定你想要得到什么(没有预期的结果),但也许这样的事情可能会有所帮助:

    1. 样本数据
      WITH 
          tbl AS
              (
                  Select 4  "ID", To_Date('25.11.2022 00:00:00', 'dd.mm.yyyy hh24:mi:ss') "START_DATE", To_Date('25.11.2022 12:00:00', 'dd.mm.yyyy hh24:mi:ss') "END_DATE" From Dual Union All
                  Select 4  "ID", To_Date('25.11.2022 12:00:00', 'dd.mm.yyyy hh24:mi:ss') "START_DATE", To_Date('26.11.2022 00:00:00', 'dd.mm.yyyy hh24:mi:ss') "END_DATE" From Dual Union All
                  Select 40 "ID", To_Date('25.11.2022 00:00:00', 'dd.mm.yyyy hh24:mi:ss') "START_DATE", To_Date('25.11.2022 06:00:00', 'dd.mm.yyyy hh24:mi:ss') "END_DATE" From Dual Union All
                  Select 40 "ID", To_Date('25.11.2022 06:00:00', 'dd.mm.yyyy hh24:mi:ss') "START_DATE", To_Date('25.11.2022 12:00:00', 'dd.mm.yyyy hh24:mi:ss') "END_DATE" From Dual Union All
                  Select 40 "ID", To_Date('25.11.2022 11:30:00', 'dd.mm.yyyy hh24:mi:ss') "START_DATE", To_Date('25.11.2022 18:00:00', 'dd.mm.yyyy hh24:mi:ss') "END_DATE" From Dual Union All
                  Select 40 "ID", To_Date('25.11.2022 18:30:00', 'dd.mm.yyyy hh24:mi:ss') "START_DATE", To_Date('25.11.2022 19:30:00', 'dd.mm.yyyy hh24:mi:ss') "END_DATE" From Dual Union All
                  Select 40 "ID", To_Date('25.11.2022 19:31:00', 'dd.mm.yyyy hh24:mi:ss') "START_DATE", To_Date('26.11.2022 00:00:00', 'dd.mm.yyyy hh24:mi:ss') "END_DATE" From Dual Union All
                  Select 50 "ID", To_Date('25.11.2022 00:00:00', 'dd.mm.yyyy hh24:mi:ss') "START_DATE", To_Date('25.11.2022 12:00:00', 'dd.mm.yyyy hh24:mi:ss') "END_DATE" From Dual Union All
                  Select 50 "ID", To_Date('25.11.2022 11:00:00', 'dd.mm.yyyy hh24:mi:ss') "START_DATE", To_Date('26.11.2022 01:30:00', 'dd.mm.yyyy hh24:mi:ss') "END_DATE" From Dual Union All
                  Select 50 "ID", To_Date('25.11.2022 23:10:00', 'dd.mm.yyyy hh24:mi:ss') "START_DATE", To_Date('25.11.2022 23:30:00', 'dd.mm.yyyy hh24:mi:ss') "END_DATE" From Dual Union All
                  Select 50 "ID", To_Date('25.11.2022 23:30:00', 'dd.mm.yyyy hh24:mi:ss') "START_DATE", To_Date('25.11.2022 23:45:00', 'dd.mm.yyyy hh24:mi:ss') "END_DATE" From Dual Union All
                  Select 50 "ID", To_Date('25.11.2022 23:50:00', 'dd.mm.yyyy hh24:mi:ss') "START_DATE", To_Date('25.11.2022 23:55:00', 'dd.mm.yyyy hh24:mi:ss') "END_DATE" From Dual 
              ), 
      
      1. 创建 CTE (day_tbl) 转换您的日期和时间以获得每日事件并记录可能延长到第二天:
          day_tbl AS
              (   Select  
                      ID,
                      START_DATE "START_DATE", 
                      ROW_NUMBER() OVER(Partition By ID Order By START_DATE) "CALL_NO",
                      To_Char(START_DATE, 'hh24:mi:ss') "START_TIME",
                      END_DATE "END_DATE", 
                      To_Char(END_DATE, 'hh24:mi:ss') "END_TIME",
                      --
                      CASE 
                            WHEN (TRUNC(START_DATE) = TRUNC(END_DATE) And To_Char(END_DATE, 'hh24:mi:ss') = '00:00:00') 
                                OR 
                                  (TRUNC(END_DATE) - TRUNC(START_DATE) = 1 AND To_Char(END_DATE, 'hh24:mi:ss') = '00:00:00')
                            THEN TRUNC(START_DATE)
                      ELSE  END_DATE
                      END "NEW_END_DATE",
                      CASE 
                            WHEN  (TRUNC(START_DATE) = TRUNC(END_DATE) And To_Char(END_DATE, 'hh24:mi:ss') = '00:00:00') 
                                OR 
                                  (TRUNC(END_DATE) - TRUNC(START_DATE) = 1 AND To_Char(END_DATE, 'hh24:mi:ss') = '00:00:00')
                            THEN '24:00:00'
                      ELSE  To_Char(END_DATE, 'hh24:mi:ss')
                      END "NEW_END_TIME",
                      --
                      CASE 
                            WHEN  (TRUNC(END_DATE) - TRUNC(START_DATE) = 1 AND To_Char(END_DATE, 'hh24:mi:ss') != '00:00:00')
                            THEN '00:00:00'
                      END "NEXT_DAY_TIME_FROM",
                      CASE 
                            WHEN  (TRUNC(END_DATE) - TRUNC(START_DATE) = 1 AND To_Char(END_DATE, 'hh24:mi:ss') != '00:00:00')
                            THEN To_Char(END_DATE, 'hh24:mi:ss')
                      END "NEXT_DAY_TIME_UNTIL"
                  From 
                      tbl 
              )
      
      1. 主 SQL 生成每个 DAY/ID 的事件,其中包含有关第一个和最后一个事件时间 (00 - 24)、连续性和扩展的信息;
      SELECT
          ID, 
          START_DATE,
          CALL_NO,
          START_TIME "CALL_START_TIME", 
          NEW_END_TIME "CALL_END_TIME",
          MIN(START_TIME) OVER(Partition By ID) "DAY_FIRST_TIME",
          MAX(NEW_END_TIME) OVER(Partition By ID) "DAY_LAST_TIME",
          CASE 
              WHEN LAG(NEW_END_TIME, 1, START_TIME) OVER(Partition By ID Order By START_DATE) > START_TIME THEN 'OVERLAP'
              WHEN LAG(NEW_END_TIME, 1, START_TIME) OVER(Partition By ID Order By START_DATE) < START_TIME THEN 'GAP'
          END "CONTINUITY",
          NEXT_DAY_TIME_UNTIL "EXTENDS_TO_NEXT_DAY_TILL"
      FROM
          day_tbl
      ORDER BY
          ID,
          START_DATE
      

      结果:

      ID START_DATE CALL_NO CALL_START_TIME CALL_END_TIME DAY_FIRST_TIME DAY_LAST_TIME CONTINUITY EXTENDS_TO_NEXT_DAY_TILL
      4 25-NOV-22 1 00:00:00 12:00:00 00:00:00 24:00:00
      4 25-NOV-22 2 12:00:00 24:00:00 00:00:00 24:00:00
      40 25-NOV-22 1 00:00:00 06:00:00 00:00:00 24:00:00
      40 25-NOV-22 2 06:00:00 12:00:00 00:00:00 24:00:00
      40 25-NOV-22 3 11:30:00 18:00:00 00:00:00 24:00:00 OVERLAP
      40 25-NOV-22 4 18:30:00 19:30:00 00:00:00 24:00:00 GAP
      40 25-NOV-22 5 19:31:00 24:00:00 00:00:00 24:00:00 GAP
      50 25-NOV-22 1 00:00:00 12:00:00 00:00:00 23:55:00
      50 25-NOV-22 2 11:00:00 01:30:00 00:00:00 23:55:00 OVERLAP 01:30:00
      50 25-NOV-22 3 23:10:00 23:30:00 00:00:00 23:55:00 GAP
      50 25-NOV-22 4 23:30:00 23:45:00 00:00:00 23:55:00
      50 25-NOV-22 5 23:50:00 23:55:00 00:00:00 23:55:00 GAP

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-19
      • 1970-01-01
      • 1970-01-01
      • 2018-03-03
      相关资源
      最近更新 更多