如何改进时间轴sql查询
我必须构建一个Oracle sql查询,将最后一天的数据聚合为15分钟的数据块。 我找到了一个有效的解决方案,但我不确定我是否把一个简单的问题弄得更复杂了 事实并非如此 为了简单起见,我想在报告中使用以下表格:如何改进时间轴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
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