所以我试图按小时将聚合(求和)值插入值表中。按小时插入值后,我想在同一过程中按天插入综合总和。有没有办法我可以让存储过程按小时完成插入,然后让它通过对在“小时”期间插入的数据进行求和来绘制光标。处理?我是否需要提交第一个事务,然后在不久之后创建另一个游标?
以下是一些示例数据:
已按小时汇总/汇总的查询结果:
SUM (VALUE_TX) UTC_OFFSET DATA_DATE HR
5 8 902018 1
10 8 902018 2
4 8 902018 3
在将上面的第一个结果集插入表格后,我想要插入的内容。我将从我将要插入的同一个表中绘制这些值。
SUM (VALUE_TX) UTC_OFFSET DATA_DATE HR
19 8 902018 null
我正在考虑做以下事情,但我不确定这是否是最好的方法。我将按data_Date分组以形成第二个游标。
Create or replace procedure AGG_HOURLY_DAILY IS
CURSOR c1 is
Select sum(value_Tx) as sum_of_values
, utc_offset
, data_date
, hr
from value
group by data_date, utc_offset, hr
where HR is not null;
l_var c1%ROWTYPE;
CURSOR c2 is
Select sum(value_tx)
, utc_offset
, data_date
, hr
group by data_date, utc_offset, hr
Where HR is null;
k_var c2%rowtype;
BEGIN
Open C1;
LOOP;
FETCH c1 into l_var;
EXIT WHEN c1%NOTFOUND;
Insert into value(value_id, value_tx, utc_offset, data_date, hr)
values(null, l_var.sum_of_values, l_var.utc_offset, l_var.data_date, l_var.hr);
END LOOP;
CLOSE C1;
OPEN C2;
LOOP;
FETCH c2 into k_var;
EXIT WHEN c2%NOTFOUND;
Insert into value(value_id, value_tx, utc_offset, data_date, hr)
values(null, l_var.sum_of_values, l_var.utc_offset, l_var.data_date, l_var.hr);
END LOOP;
Close c1;
Close c2;
END AGG_HOURLY_DAILY;
注意:Value_ID由我创建的序列/触发器自动生成
答案 0 :(得分:2)
也许你想要这样的东西:
with demo (value_tx, utc_offset, data_date, hr)
as ( select 1, 8, '902018', 1 from dual union all
select 2, 8, '902018', 1 from dual union all
select 2, 8, '902018', 1 from dual union all
select 4, 8, '902018', 2 from dual union all
select 6, 8, '902018', 2 from dual union all
select 1, 8, '902018', 3 from dual union all
select 2, 8, '902018', 3 from dual union all
select 1, 8, '902018', 3 from dual )
select sum(value_tx), utc_offset, data_date, hr
from demo
group by grouping sets ((utc_offset, data_date, hr), (utc_offset, data_date))
order by hr nulls last;
SUM(VALUE_TX) UTC_OFFSET DATA_DATE HR
------------- ---------- --------- ----------
5 8 902018 1
10 8 902018 2
4 8 902018 3
19 8 902018
GROUPING SETS
子句实际上是说您需要两个GROUP BY
操作:一个在(utc_offset, data_date, hr)
上,另一个在(utc_offset, data_date)
上。
答案 1 :(得分:1)
在第一步中,用简单的INSERT ... SELECT语句替换游标:
Insert into value( value_tx, utc_offset, data_date, hr)
SELECT sum(value_Tx) as sum_of_values
, utc_offset
, data_date
, hr
from value
group by data_date, utc_offset, hr
where HR is not null;
Insert into value( value_tx, utc_offset, data_date, hr)
Select sum(value_tx)
, utc_offset
, data_date
, hr
group by data_date, utc_offset, hr
Where HR is null;
由于这种简化,很容易看出两个查询只有一个元素不同:HR is NULL
和HR is NOT NULL
。
因此,上面插入两行的两个查询可以简化为插入相同两行的一个:
Insert into value( value_tx, utc_offset, data_date, hr)
SELECT sum_tx, utc_offset, data_date, hr
FROM (
Select CASE WHEN hr IS NULL THEN 1 ELSE 2 END as xxx
, sum(value_tx) as sum_tx
, utc_offset
, data_date
, hr
group by CASE WHEN hr IS NULL THEN 1 ELSE 2 END,
data_date, utc_offset, hr
)
;
所以我不需要PL / SQL吗?有没有办法可以做到这一点 使用PL / SQL?
您可以在程序中执行此操作,无需程序即可 如果你想要一个程序,只需:
Create or replace procedure AGG_HOURLY_DAILY IS
BEGIN
Insert into value( value_tx, utc_offset, data_date, hr)
SELECT sum_tx, utc_offset, data_date, hr
FROM (
Select CASE WHEN hr IS NULL THEN 1 ELSE 2 END as xxx
, sum(value_tx) as sum_tx
, utc_offset
, data_date
, hr
group by CASE WHEN hr IS NULL THEN 1 ELSE 2 END,
data_date, utc_offset, hr
)
;
END;
/