oracle sql 查询进一步优化 1

oracle sql query optimization further 1

我已经从 bdb 向 select * 编写了一个查询,以仅获取最新 ACT 中 DAY、INST 组合的 PRICE 更新值 我创建了一个 table 喜欢

CREATE TABLE bdb(
   ACT  NUMBER(8) NOT NULL,
   INST NUMBER(8) NOT NULL,
   DAY  DATE      NOT NULL,
   PRICE  VARCHAR2 (3),
   CURR   NUMBER (8,2),
   PRIMARY KEY (ACT,INST,DAY)
);

用它来填充 table

DECLARE
   t_day  bdb.day%type:= '1-JAN-16';
   n pls_integer;
BEGIN


<< act_loop >>
FOR i IN 1..3 LOOP --NUMBER OF ACT i
    << inst_loop >>
    FOR j IN 1..1000 LOOP --NUMBER OF INST j
        t_day:='3-JAN-16';
        << day_loop >>
        FOR k IN 1..260 LOOP --NUMBER OF DAYS k
            n:= dbms_random.value(1,3);
            INSERT into bdb (ACT,INST,DAY,PRICE,CURR) values (i,j,t_day,n,10.3);
            t_day:=t_day+1;
        END loop day_loop;

    END loop inst_loop;
END loop act_loop;

END;
/

使用这个查询 我只得到 DAY,INST,PRICE

select day,inst,price from bdb where (act=(select max(act) from bdb))
minus
select day,inst,price from bdb where act=(select max(act)-1 from bdb);

上面一个是fast.but 我想以高效的方式获取所有字段。 我想出的那个有点慢,就是这个,

select 
    e1.* 
from 
    (select 
        * 
    from 
        bdb 
    where 
        (act=(select max(act) from bdb))
    )e1,
(select day,inst,price from bdb where (act=(select max(act) from bdb))
minus
select day,inst,price from bdb where act=(select max(act)-1 from bdb)) e2
where 
e1.day=e2.day and e1.inst=e2.inst;

任何人都可以就如何进一步优化它提出任何建议吗?或者不使用两个 table 的交叉连接如何获得所需的 output.Help 我 ;)

我只需要

     ACT  INST     DAY      PRI   CURR
    ------------------------------------
     3    890 05-MAR-16     3     10.3
     3    890 06-MAR-16     2     10.3
     3    890 07-MAR-16     2     10.3

     3    891 05-MAR-16     2     10.3
     3    891 06-MAR-16     1     10.3
     3    891 07-MAR-16     2     10.3

     4    890 05-MAR-16     3     10.3
     4    890 06-MAR-16     2     10.3
     4    890 07-MAR-16     1     10.3

     4    891 05-MAR-16     2     10.3
     4    891 06-MAR-16     2     10.3
     4    891 07-MAR-16     1     10.3

这里是 (890,05-MAR-16) (890,06-MAR-16) (890,06-MAR-16) (891,05-MAR-16) (891,06-MAR-16) (891,06-MAR-16) 在行为=3 价格是 3,2,2 2,1,2

but when act=4 happens
        (890,07-MAR-16) 
        (891,06-MAR-16)
        (891,07-MAR-16) 
        price values are change from what they were in act=3.
        others not change

最终我需要的是

    ACT   INST     DAY     PRI    CURR
    ------------------------------------
     4    890 07-MAR-16     1     10.3
     4    891 06-MAR-16     2     10.3
     4    891 07-MAR-16     1     10.3

您似乎在计算当天、inst 和 price 值,其中有一行的 act 列在整个 table 中具有最大的 act 值,但没有一行act 列比最大 act 值小一。

你可以试试这个:

SELECT day,
       inst,
       price
FROM   (SELECT day,
               inst,
               price,
               act,
               MAX(act) OVER () max_overall_act
        FROM   bdb)
WHERE  act IN (max_overall_act, max_overall_act -1)
GROUP BY day, inst, price
HAVING MAX(CASE WHEN act = max_overall_act THEN 1 END) = 1
AND    MAX(CASE WHEN act = max_overall_act - 1 THEN 1 END) IS NULL;

首先,子查询找到整个table中的最大act值。

然后我们select所有行为值是最大值或小于最大值的行。

之后,我们对行进行分组,找出哪些行具有 act = max act val,但没有 act = max act val -1。


但是,根据您在 post 中所说的:

I have written a query to select * from bdb to get only updated values in PRICE for the combination of DAY,INST in the newest ACT

您提出的查询和我回答中的上述查询似乎都不符合您的要求。

我认为你在寻找类似的东西:

SELECT act,
       inst,
       DAY,
       price,
       curr,
       prev_price -- if desired
FROM   (SELECT act,
               inst,
               DAY,
               price,
               curr,
               LEAD(price) OVER (PARTITION BY inst, DAY ORDER BY act DESC) prev_price,
               row_number() OVER (PARTITION BY inst, DAY ORDER BY act DESC) rn
        FROM   bdb)
WHERE  rn = 1
AND    prev_price != price;

它的作用是使用 LEAD() 分析(基于降序行为顺序)来查找每一天每一天的前一行为行的价格,以及行号。

然后要找到最新的行为行,我们只需 select rownumber 为 1 且先前价格与当前价格不匹配的行。然后,如果需要,您可以同时显示当前价格和之前的价格。