重写正在运行的total sql查询
我想重写下面的SQL,使其更有效,可能使用Oracle分析函数,但任何有效的重写都可以。SQL当前运行正常,只需一段时间即可运行:- 创建表:重写正在运行的total sql查询,sql,oracle,rewrite,Sql,Oracle,Rewrite,我想重写下面的SQL,使其更有效,可能使用Oracle分析函数,但任何有效的重写都可以。SQL当前运行正常,只需一段时间即可运行:- 创建表: CREATE TABLE ITEM_REF ( DEPT_ID VARCHAR2(5 BYTE) NOT NULL , ID VARCHAR2(11 BYTE) NOT NULL , ID_TYPE VARCHAR2(1 BYTE) NOT NULL , ITEM_CHARGE VARCHAR2(15 BYTE) NOT NULL , IT
CREATE TABLE ITEM_REF
(
DEPT_ID VARCHAR2(5 BYTE) NOT NULL
, ID VARCHAR2(11 BYTE) NOT NULL
, ID_TYPE VARCHAR2(1 BYTE) NOT NULL
, ITEM_CHARGE VARCHAR2(15 BYTE) NOT NULL
, ITEM_PAYMENT VARCHAR2(15 BYTE) NOT NULL
, ITEM_DATE DATE NOT NULL
, REF_AMT NUMBER(14, 2) NOT NULL
)
在表中插入:
INSERT INTO ITEM_REF VALUES ('POLLD', '0004', 'O', '000000000000001', '000000000000002', '11/JUN/09', '1550')
INSERT INTO ITEM_REF VALUES ('POLLD', '0004', 'O', '000000000000003', '000000000000004', '23/OCT/09', '3100')
INSERT INTO ITEM_REF VALUES ('POLLD', '0004', 'O', '000000000000005', '000000000000007', '02/AUG/10', '3500')
INSERT INTO ITEM_REF VALUES ('POLLD', '0004', 'O', '000000000000008', '000000000000010', '15/DEC/10', '3500')
INSERT INTO ITEM_REF VALUES ('POLLD', '0004', 'O', '000000000000003', '000000000000004', '14/APR/11', '0')
INSERT INTO ITEM_REF VALUES ('POLLD', '0004', 'O', '000000000000012', '000000000000014', '14/APR/11', '3100')
INSERT INTO ITEM_REF VALUES ('POLLD', '0004', 'O', '000000000000021', '000000000000022', '13/JUL/11', '3500')
INSERT INTO ITEM_REF VALUES ('POLLD', '0004', 'O', '000000000000016', '000000000000018', '03/JUN/11', '1550')
INSERT INTO ITEM_REF VALUES ('POLLD', '0004', 'O', '000000000000016', '000000000000018', '22/JUN/11', '0')
INSERT INTO ITEM_REF VALUES ('POLLD', '0004', 'O', '000000000000017', '000000000000019', '22/JUN/11', '1550')
INSERT INTO ITEM_REF VALUES ('POLLD', '0004', 'O', '000000000000005', '000000000000007', '13/JUL/11', '0')
INSERT INTO ITEM_REF VALUES ('POLLD', '0004', 'O', '000000000000021', '000000000000022', '19/SEP/11', '0')
INSERT INTO ITEM_REF VALUES ('POLLD', '0004', 'O', '000000000000021', '000000000000024', '19/SEP/11', '3500')
INSERT INTO ITEM_REF VALUES ('POLLD', '0004', 'O', '000000000000023', '000000000000025', '21/NOV/11', '1550')
INSERT INTO ITEM_REF VALUES ('POLLD', '0004', 'O', '000000000000027', '000000000000030', '03/NOV/14', '384')
INSERT INTO ITEM_REF VALUES ('POLLD', '0004', 'O', '000000000000028', '000000000000030', '03/NOV/14', '247.8')
INSERT INTO ITEM_REF VALUES ('POLLD', '0004', 'O', '000000000000026', '000000000000029', '27/OCT/14', '2465')
INSERT INTO ITEM_REF VALUES ('POLLD', '0002', 'O', '000000000000001', '000000000000004', '07/JUL/10', '88.4')
INSERT INTO ITEM_REF VALUES ('POLLD', '0002', 'O', '000000000000001', '000000000000004', '13/JUL/10', '88.4')
INSERT INTO ITEM_REF VALUES ('POLLD', '0002', 'O', '000000000000001', '000000000000006', '17/AUG/10', '353.6')
INSERT INTO ITEM_REF VALUES ('POLLD', '0002', 'O', '000000000000001', '000000000000004', '21/AUG/10', '88.4')
INSERT INTO ITEM_REF VALUES ('POLLD', '0002', 'O', '000000000000001', '000000000000006', '21/AUG/10', '87.6')
INSERT INTO ITEM_REF VALUES ('POLLD', '0002', 'O', '000000000000001', '000000000000006', '25/AUG/10', '353.6')
当前正在运行的SQL总数:
SELECT A.DEPT_ID, A.ID, A.ID_TYPE, A.ITEM_CHARGE, A.ITEM_DATE
, NVL((SELECT SUM(B.REF_AMT) FROM ITEM_REF B
WHERE B.DEPT_ID = A.DEPT_ID
AND B.ID = A.ID
AND B.ID_TYPE = A.ID_TYPE
AND B.ITEM_CHARGE = A.ITEM_CHARGE
AND B.ITEM_DATE =
(SELECT MAX(B2.ITEM_DATE)
FROM ITEM_REF B2
WHERE B2.DEPT_ID = B.DEPT_ID
AND B2.ID = B.ID
AND B2.ID_TYPE = B.ID_TYPE
AND B2.ITEM_CHARGE = B.ITEM_CHARGE
AND B2.ITEM_PAYMENT = B.ITEM_PAYMENT
AND B2.ITEM_DATE <= A.ITEM_DATE)
), 0)
FROM ITEM_REF A GROUP BY A.DEPT_ID, A.ID, A.ID_TYPE, A.ITEM_CHARGE, A.ITEM_DATE
我尝试使用Oracle分析函数,如下所示:-
SELECT A.DEPT_ID
, A.ID
, A.ID_TYPE
, A.ITEM_CHARGE
, A.ITEM_DATE
, (SELECT SUM(B.REF_AMT)
FROM ITEM_REF B
WHERE B.DEPT_ID =A.DEPT_ID
AND B.ID =A.ID
AND B.ID_TYPE =A.ID_TYPE
AND B.ITEM_CHARGE =A.ITEM_CHARGE
AND B.ITEM_DATE =
(SELECT C.ITEM_DATE
FROM
(SELECT D.ITEM_DATE
, ROW_NUMBER() OVER (PARTITION BY D.DEPT_ID, D.ID, D.ID_TYPE, D.ITEM_CHARGE, D.ITEM_PAYMENT ORDER BY D.ITEM_DATE DESC) RN
FROM ITEM_REF D
WHERE D.ITEM_DATE <= A.ITEM_DATE
) C
WHERE C.RN =1
)
)
FROM ITEM_REF A
对A.ITEM_DATE的引用破坏了这段代码,因为内部SQL无法引用表ITEM_REF A。这里我的方法是使用Oracle分析函数从主SQL表(即ITEM_REF A)返回到给定日期的最大ITEM_DATE。
谢谢更新的答案
在开始处使用数据分组进行查询,并使用行号对行进行排序。我认为分组后,如果行数少一些可能会更好。对750000行进行了测试,新版本速度更快。
但我更喜欢你的查询,它更具可读性-
with ds as (select dept_id, id, id_type, item_charge, item_date, item_payment, sum(ref_amt) ref_amt
from item_ref
group by dept_id, id, id_type, item_charge, item_date, item_payment),
dsp as (
select ds1.dept_id, ds1.id, ds1.id_type, ds1.item_charge, ds1.item_date, ds2.ref_amt,
row_number() over (partition by ds2.dept_id, ds2.id, ds2.id_type, ds2.item_charge,
ds2.item_payment, ds1.item_date order by ds2.item_date desc) rn
from ds ds1 join ds ds2 on ds2.dept_id=ds1.dept_id and ds2.id=ds1.id and ds2.id_type=ds1.id_type
and ds2.item_charge=ds1.item_charge and ds2.item_date<=ds1.item_date)
select dept_id, id, id_type, item_charge, item_date, sum(ref_amt)
from dsp where rn=1
group by dept_id, id, id_type, item_charge, item_date
如果你想获得增加的金额,你可以使用类似amt\u aggr的东西 欢迎来到堆栈溢出!这是一个你可以就你所写的软件所遇到的问题提问并获得答案的网站,但它不是一个为我做作业或为我做工作的网站。当你问一个问题时,你应该包括你写的代码和你得到的具体错误,或者你的程序产生的结果,以及对你期望的结果的解释。没有这一点,我们真的没有什么可以帮助你的。请编辑您的问题以显示您所做的工作,并告诉我们代码存在哪些问题。再次欢迎使用堆栈溢出!您还可以快速创建表项\u REF和一些语句,将一些示例数据插入其中,这样我们就可以再次使用/运行它了。那么应该是B2,还是B_ED?我已经添加了关于我的尝试和示例数据的更多信息。您是对的,您的代码在给定初始示例数据的情况下运行良好。请使用更新的样本数据进行尝试。项目付款影响参考金额的总和。也感谢您的回复。感谢更新的、更好的示例,尝试了一些查询,但到目前为止没有成功。还有一个提示-您可以尝试在部门ID、ID、ID类型、项目费用、项目日期上添加复合索引,这可能会大大加快执行速度。
select dept_id, id, id_type, item_charge, item_date,
sum(ref_amt) amt,
sum(sum(ref_amt)) over (partition by dept_id, id, id_type, item_charge
order by item_date) amt_aggr
from item_ref a
group by dept_id, id, id_type, item_charge, item_date