Sql 100个逗号分隔的随机计数器位置值构成一个总和,并显示最近60分钟的统计数据
我试图在pentaho仪表板上显示最近60分钟的统计数据(oracle 11g查询传递给pentaho)。 我的表中有一列(counter_buff),有1000个计数器位置,示例数据如下所示Sql 100个逗号分隔的随机计数器位置值构成一个总和,并显示最近60分钟的统计数据,sql,oracle,pentaho,Sql,Oracle,Pentaho,我试图在pentaho仪表板上显示最近60分钟的统计数据(oracle 11g查询传递给pentaho)。 我的表中有一列(counter_buff),有1000个计数器位置,示例数据如下所示 counter_buff= '0,8,9,3,2,6,....15,62' up to 1000 comma seperated values 我试图根据提供的固定位置从表中获取每个逗号分隔的值,并对它们求和,所以问题是,如果我使用多个位置,查询会变得更大&越慢,查询结果越慢,仪表板上的统计数据就会
counter_buff= '0,8,9,3,2,6,....15,62' up to 1000 comma seperated values
我试图根据提供的固定位置从表中获取每个逗号分隔的值,并对它们求和,所以问题是,如果我使用多个位置,查询会变得更大&越慢,查询结果越慢,仪表板上的统计数据就会延迟
我创建了以下示例查询和结果:
查询:
{}中显示的数字是计数器位置({16},{24}..),此位置将由用户定义。同样使用6个union进行查询,如下所示
select * from
((SELECT MIN(to_char(TIMESTAMP,'HH24:MI:SS')) as TS,
'SELL' as "STATUS",
SUM((regexp_substr(counter_buff,'(.*?,){16}(.*?),', 1, 1,'', 2)) +
(regexp_substr(counter_buff,'(.*?,){24}(.*?),', 1, 1,'', 2)) +
(regexp_substr(counter_buff,'(.*?,){32}(.*?),', 1, 1,'', 2)) ......+
(regexp_substr(counter_buff,'(.*?,){168}(.*?),', 1, 1,'', 2))) AS "COUNTS"
FROM (SELECT * FROM SHOPS
order by TO_CHAR("TIMESTAMP",'YYYY-MM-DD HH24:MI:SS') desc) "SHOPS"
where TOY_NAME = 'LION'
and rownum <=60
GROUP BY TO_CHAR("TIMESTAMP",'HH24:MI'))
UNION ALL
(SELECT MIN(to_char(TIMESTAMP,'HH24:MI:SS')) as TS,
'RETURNED' as "STATUS",
SUM((regexp_substr(counter_buff,'(.*?,){17}(.*?),', 1, 1,'', 2)) +
(regexp_substr(counter_buff,'(.*?,){25}(.*?),', 1, 1,'', 2)) ..... +
(regexp_substr(counter_buff,'(.*?,){153}(.*?),', 1, 1,'', 2)) +
(regexp_substr(counter_buff,'(.*?,){161}(.*?),', 1, 1,'', 2)) +
(regexp_substr(counter_buff,'(.*?,){169}(.*?),', 1, 1,'', 2))) AS "COUNTS"
FROM (SELECT * FROM SHOPS
order by TO_CHAR("TIMESTAMP",'YYYY-MM-DD HH24:MI:SS') desc) "SHOPS"
where TOY_NAME = 'LION'
and rownum <=60
GROUP BY TO_CHAR("TIMESTAMP",'HH24:MI')) )
order by TS desc,STATUS desc
我能够实现我想要的输出,但是我想要更快更小的查询选项
我不熟悉oracle query您应该首先尽可能多地过滤数据,然后完成其余的工作。另外,不需要使用
联合
,您可以在一个分组中执行所有操作,然后仅在需要时取消PIVOT结果。
下面是两个查询,应该很有用。首先,您必须根据需要多次编写regexp\u substr
:
/* sample data
with shops(toy_name, time_stamp, counter_buff) as (
select 'LION', timestamp '2018-07-27 13:15:27', '0,8,9,3,2,6,15,62' from dual union all
select 'BEAR', timestamp '2018-07-27 13:44:06', '7,3,9,3,3,6,11,39' from dual union all
select 'LION', timestamp '2018-07-27 16:03:09', '7,3,151,44,3,6,11,39' from dual union all
select 'LION', timestamp '2018-07-27 16:03:49', '7,3,11,4,3,6,11,39' from dual )
-- end of data */
select to_char(time_stamp, 'hh24:mi') ts,
sum(regexp_substr(counter_buff,'(.*?,){2}(.*?),', 1, 1,'', 2) +
regexp_substr(counter_buff,'(.*?,){5}(.*?),', 1, 1,'', 2)) sell,
sum(regexp_substr(counter_buff,'(.*?,){3}(.*?),', 1, 1,'', 2) +
regexp_substr(counter_buff,'(.*?,){6}(.*?),', 1, 1,'', 2)) retu
from (select time_stamp, counter_buff, row_number() over (order by time_stamp desc) rn
from shops where toy_name = 'LION') t
where rn <= 60
group by to_char(time_stamp, 'hh24:mi')
在这两个查询中,我假设
sell
处于位置(2,5),返回的处于位置(3,6)。还可以尝试对rownum
执行row\u number()
,并检查哪个更快。在这两种情况下,数据只命中一次,这将加快计算速度。使用数据库时,如果您对单独的值不感兴趣,请仅存储逗号分隔的值。如果您对单独的值感兴趣,请分别存储它们。
/* sample data
with shops(toy_name, time_stamp, counter_buff) as (
select 'LION', timestamp '2018-07-27 13:15:27', '0,8,9,3,2,6,15,62' from dual union all
select 'BEAR', timestamp '2018-07-27 13:44:06', '7,3,9,3,3,6,11,39' from dual union all
select 'LION', timestamp '2018-07-27 16:03:09', '7,3,151,44,3,6,11,39' from dual union all
select 'LION', timestamp '2018-07-27 16:03:49', '7,3,11,4,3,6,11,39' from dual )
-- end of data */
select to_char(time_stamp, 'hh24:mi') ts,
sum(regexp_substr(counter_buff,'(.*?,){2}(.*?),', 1, 1,'', 2) +
regexp_substr(counter_buff,'(.*?,){5}(.*?),', 1, 1,'', 2)) sell,
sum(regexp_substr(counter_buff,'(.*?,){3}(.*?),', 1, 1,'', 2) +
regexp_substr(counter_buff,'(.*?,){6}(.*?),', 1, 1,'', 2)) retu
from (select time_stamp, counter_buff, row_number() over (order by time_stamp desc) rn
from shops where toy_name = 'LION') t
where rn <= 60
group by to_char(time_stamp, 'hh24:mi')
with
/* sample data
shops(toy_name, time_stamp, counter_buff) as (
select 'LION', timestamp '2018-07-27 13:15:27', '0,8,9,3,2,6,15,62' from dual union all
select 'BEAR', timestamp '2018-07-27 13:44:06', '7,3,9,3,3,6,11,39' from dual union all
select 'LION', timestamp '2018-07-27 16:03:09', '7,3,151,44,3,6,11,39' from dual union all
select 'LION', timestamp '2018-07-27 16:03:49', '7,3,11,4,3,6,11,39' from dual ),
*/ -- end of sample data
sell as (select rownum rn, column_value cs from table(sys.odcinumberlist(2, 5)) ),
retu as (select rownum rn, column_value cr from table(sys.odcinumberlist(3, 6)) )
select *
from (
select sum(regexp_substr(counter_buff,'(.*?,){'||cs||'}(.*?),', 1, 1,'', 2)) sell,
sum(regexp_substr(counter_buff,'(.*?,){'||cr||'}(.*?),', 1, 1,'', 2)) retu, ts
from (select to_char(time_stamp, 'HH24:MI') ts, counter_buff
from (select * from shops where toy_name = 'LION' order by time_stamp desc)
where rownum <= 60)
cross join sell join retu using (rn) group by ts)
unpivot (val for status in (sell, retu))