所以,我有一些with_options的表结构(使用此链接获取信息)
我需要从0到10(在示例中)逐个排除日期数(列cnt),还可以排除列标志中值为1的其他列。
最后,我需要根据非排除值获得最高的koef平均值。
主要思想是根据较高的条件,通过从计算中排除行来获得最高平均值。
任何人都知道如何处理这项任务?
答案 0 :(得分:1)
此查询看起来很有希望:
select *
from (
with
data as (select row_number() over (order by m_dt) rn, dat.* from dat),
numbers as (select level n from dual connect by level<=10)
select rn, m_dt, n, 0 flags,
(select avg(koef) from data where rn not between d.rn and d.rn + n - 1) av
from data d, numbers
union all
select rn, m_dt, n, 1,
(select avg(koef) from data
where flag = 1 or rn not between d.rn and d.rn + n - 1) av
from data d, numbers
order by av desc)
where rownum = 1
我希望我能够理解你的讨论和澄清,但即使不是 - 也许这些代码中的一部分会很有用。
对于表中的每个日期,查询将消除1到10个连续行,并为其余行计数avg
。
当我们将flag = 1的行添加到已消除的集合时,也会执行相同的操作。外部查询选择平均值最高的行。
这里也是PL / SQL版本(远非最优,我只是写了一些东西来检查SQL解决方案的结果 - 两种解决方案都产生了相同的最佳方案):
create or replace procedure miner is
v_best_avg number := 0;
v_curr_avg number := 0;
v_max_cnt number := 10;
begin
for v_cnt in 1..v_max_cnt
loop
for o in (select row_number() over (order by m_dt) rn, dat.* from dat)
loop
select avg(koef) into v_curr_avg
from (select row_number() over (order by m_dt) rn, dat.* from dat)
where rn not between o.rn and o.rn + v_cnt - 1;
if v_curr_avg > v_best_avg then
v_best_avg := v_curr_avg;
dbms_output.put_line(trunc(v_curr_avg, 4)||' '
||to_char(o.m_dt, 'yyyy-mm-dd')||' '||v_cnt||' '||'flags not excluded');
end if;
select avg(koef) into v_curr_avg
from (select row_number() over (order by m_dt) rn, dat.* from dat)
where flag = 1 or rn not between o.rn and o.rn + v_cnt - 1;
if v_curr_avg > v_best_avg then
v_best_avg := v_curr_avg;
dbms_output.put_line(trunc(v_curr_avg, 4)||' '
||to_char(o.m_dt, 'yyyy-mm-dd')||' '||v_cnt||' '||'flags not excluded');
end if;
end loop;
end loop;
end miner;