2016-11-16 58 views
0

我已经写了一个查询,以便从BDB选择*只得到更新的价格值DAY的组合,INST在最新的ACT 我创建的表像的Oracle SQL查询优化另外1

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) 
); 

使用该使用此查询 我得到的只是一天,INST来填充表

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; 
/

,价格

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); 

以上是快速的,但我想以有效的方式获得所有的领域。 一个我想出了有点慢这是本,

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; 

谁能给任何建议,如何更多的优化呢?或出使用交叉连接两个表如何获得所需的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)in act = 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 

回答

0

它看起来像是在一天之后,inst和价格值有一行,其中act列具有整个表中最大的行为值,但没有行的行列比最大行为值小1。

你可以试试这个:

所有的
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; 

首先,子查询发现在整个表中的最高行为的价值。

然后我们选择行为值为最大值或小于此值的所有行。

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


然而,从你在你的文章中说:

我已经写了一个查询SELECT * FROM BDB只得到更新的价格值DAY的组合,INST在最新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()分析(基于递减法量级)找到该行的报价与前期为每一天和每一天行动,以及行号。

然后,要查找最新的act行,我们只需选择rownumber为1的行以及之前的价格与当前价格不匹配的行。如果您愿意,您可以显示当前和以前的价格。

+0

感谢您的快速回复...我想我没有正确解释问题....我认为这将明确阐明它。更新的问题是 – Noah

+0

你的第一个解释是正确的...但我需要他们与他们的ACT和CURR领域有效的方式 – Noah

+0

道歉;我错过了我的第二个查询中的'AND prev_price!= price'条件。这应该现在工作。 – Boneist