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 且先前价格与当前价格不匹配的行。然后,如果需要,您可以同时显示当前价格和之前的价格。
我已经从 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 且先前价格与当前价格不匹配的行。然后,如果需要,您可以同时显示当前价格和之前的价格。