如何改进时间轴sql查询

如何改进时间轴sql查询,sql,oracle,Sql,Oracle,我必须构建一个Oracle sql查询,将最后一天的数据聚合为15分钟的数据块。 我找到了一个有效的解决方案,但我不确定我是否把一个简单的问题弄得更复杂了 事实并非如此 为了简单起见,我想在报告中使用以下表格: select 1 as reportval, sysdate - 1/5 as dc from dual union select 3, sysdate - 1/3 from dual

我必须构建一个Oracle sql查询,将最后一天的数据聚合为15分钟的数据块。 我找到了一个有效的解决方案,但我不确定我是否把一个简单的问题弄得更复杂了 事实并非如此

为了简单起见,我想在报告中使用以下表格:

select 1 as reportval, sysdate - 1/5 as dc from dual
                        union
                        select 3, sysdate - 1/3 from dual
                        union
                        select 4, sysdate - 1/5 from dual
                        union
                        select 5, sysdate - 1/4 from dual
因此,我构建了一个查询,以获取最后一天的时间线:

SELECT LEVEL
                   , CASE
                        WHEN CAST (
                                TO_CHAR (SYSDATE - ( (60 / 86400) * LEVEL * 15)
                                       , 'MI') AS NUMBER) BETWEEN 0
                                                              AND 14 THEN
                              TO_CHAR (SYSDATE - ( (60 / 86400) * LEVEL * 15)
                                     , 'ddmmyyyyHH24')
                           || '00'
                        WHEN CAST (
                                TO_CHAR (SYSDATE - ( (60 / 86400) * LEVEL * 15)
                                       , 'MI') AS NUMBER) BETWEEN 15
                                                              AND 29 THEN
                              TO_CHAR (SYSDATE - ( (60 / 86400) * LEVEL * 15)
                                     , 'ddmmyyyyHH24')
                           || '15'
                        WHEN CAST (
                                TO_CHAR (SYSDATE - ( (60 / 86400) * LEVEL * 15)
                                       , 'MI') AS NUMBER) BETWEEN 30
                                                              AND 44 THEN
                              TO_CHAR (SYSDATE - ( (60 / 86400) * LEVEL * 15)
                                     , 'ddmmyyyyHH24')
                           || '30'
                        WHEN CAST (
                                TO_CHAR (SYSDATE - ( (60 / 86400) * LEVEL * 15)
                                       , 'MI') AS NUMBER) BETWEEN 45
                                                              AND 59 THEN
                              TO_CHAR (SYSDATE - ( (60 / 86400) * LEVEL * 15)
                                     , 'ddmmyyyyHH24')
                           || '45'
                     END
                        AS timeinterval
                FROM DUAL
          CONNECT BY LEVEL <= 96
选择级别
案例
铸造时(
至字符(系统日期-((60/86400)*级别*15)
,“MI”)作为数字)介于0之间
然后是14岁
至字符(系统日期-((60/86400)*级别*15)
,'ddmmyyyyh24')
|| '00'
铸造时(
至字符(系统日期-((60/86400)*级别*15)
,“MI”)作为数字)介于15之间
然后是29岁
至字符(系统日期-((60/86400)*级别*15)
,'ddmmyyyyh24')
|| '15'
铸造时(
至字符(系统日期-((60/86400)*级别*15)
,“MI”)作为数字)介于30之间
然后呢
至字符(系统日期-((60/86400)*级别*15)
,'ddmmyyyyh24')
|| '30'
铸造时(
至字符(系统日期-((60/86400)*级别*15)
,“MI”)作为数字)介于45之间
然后呢
至字符(系统日期-((60/86400)*级别*15)
,'ddmmyyyyh24')
|| '45'
结束
作为时间间隔
来自双重

按级别连接避免执行所有CASE和to_CHAR的一种方法是使用间隔DAY-to-SECOND数据类型。您可以获得如下时间线查询:

select level chunkid
     , trunc(sysdate)
         + numtodsinterval(15 * (level-1), 'minute') interval_from
     , trunc(sysdate)
         + numtodsinterval(15 * (level), 'minute')
         - interval '1' second interval_to
  from dual
 connect by level <= 96
选择级别chunkid
,trunc(sysdate)
+numtodsinterval(15*(1级),“分钟”)间隔
,trunc(sysdate)
+numtodsinterval(15*(级别),“分钟”)
-间隔“1”秒间隔\u至
来自双重

按级别连接避免执行所有CASE和to_CHAR的一种方法是使用间隔DAY-to-SECOND数据类型。您可以获得如下时间线查询:

select level chunkid
     , trunc(sysdate)
         + numtodsinterval(15 * (level-1), 'minute') interval_from
     , trunc(sysdate)
         + numtodsinterval(15 * (level), 'minute')
         - interval '1' second interval_to
  from dual
 connect by level <= 96
选择级别chunkid
,trunc(sysdate)
+numtodsinterval(15*(1级),“分钟”)间隔
,trunc(sysdate)
+numtodsinterval(15*(级别),“分钟”)
-间隔“1”秒间隔\u至
来自双重

按级别连接是的,非常有用。而且很优雅。非常感谢。是的,非常有用。而且很优雅。非常感谢。我看到了不必要的接近投票。我看到了不必要的接近投票。
with intervals as (
   select level chunkid
        , trunc(sysdate)
            + numtodsinterval(15 * (level-1), 'minute') interval_from
        , trunc(sysdate)
            + numtodsinterval(15 * (level), 'minute')
            - interval '1' second interval_to
     from dual
    connect by level <= 96
), datatable as (
   select 1 as reportval, sysdate - 1/5 as dc from dual
   union all
   select 3, sysdate - 1/3 from dual
   union all
  select 4, sysdate - 1/5 from dual
   union all
   select 5, sysdate - 1/4 from dual
)
select i.chunkid
     , sum(d.reportval)
  from intervals i
  left outer join datatable d
      on d.dc between i.interval_from and i.interval_to
 group by i.chunkid
 order by i.chunkid
with intervals as (
   select trunc(sysdate)
            + numtodsinterval(15 * (level-1), 'minute') interval_from
        , trunc(sysdate)
            + numtodsinterval(15 * (level), 'minute')
            - interval '1' second interval_to
     from dual
    connect by level <= 96
), datatable as (
   select 1 as reportval, sysdate - 1/5 as dc from dual
   union all
   select 3, sysdate - 1/3 from dual
   union all
   select 4, sysdate - 1/5 from dual
   union all
   select 5, sysdate - 1/4 from dual
)
select i.interval_from
     , sum(d.reportval)
  from intervals i
  left outer join datatable d
      on d.dc between i.interval_from and i.interval_to
 group by i.interval_from
 order by i.interval_from