如何进一步调优这个SELECT查询,或者这是唯一有效的方法?我使用的是Oracle Exadata 19 c。
它在不同的条件下多次联接两个表,并将数据作为不同的列返回。
有更好的办法,但我不知道是什么。
要试用的DDL/DML:
CREATE TABLE TRAN (
C1 VARCHAR2(50) NOT NULL,
C2 VARCHAR2(50),
C3 VARCHAR2(50),
C4 VARCHAR2(50),
C5 VARCHAR2(50),
C6 VARCHAR2(50),
C7 VARCHAR2(50),
C8 VARCHAR2(50),
C9 VARCHAR2(50)
);
CREATE TABLE ADDR (
C1 VARCHAR2(50) NOT NULL,
C2 VARCHAR2(50),
BRANCH VARCHAR2(50),
ADDR VARCHAR2(50)
);
insert into TRAN (C1, C2, C3, C4, C5, C6, C7, C8, C9) values ('A111', 'Q1', 'Q1', 'Q1', 'Q1', 'Q1', 'Q1', 'Q1', 'Q1');
insert into TRAN (C1, C2, C3, C4, C5, C6, C7, C8, C9) values ('A222', 'Q2', 'Q2', 'Q2', null, null, null, null, 'Q2');
insert into TRAN (C1, C2, C3, C4, C5, C6, C7, C8, C9) values ('A333', 'Q3', 'Q3', 'Q3', 'Q3', 'Q3', 'Q3', 'Q3', 'Q3');
insert into TRAN (C1, C2, C3, C4, C5, C6, C7, C8, C9) values ('A444', null, null, null, null, 'Q4', 'Q4', 'Q4', 'Q4');
insert into ADDR (C1, C2, BRANCH, ADDR) values ('A111', 'Q1', 'CHN', 'INDIA');
insert into ADDR (C1, C2, BRANCH, ADDR) values ('A222', 'Q2','BLR', 'USA');
insert into ADDR (C1, C2, BRANCH, ADDR) values ('A444', 'Q4', 'HYD', 'UK');
commit;
选择查询:
WITH T1 as (SELECT tran.* FROM tran),
T2 as (SELECT ADDR.* FROM ADDR)
SELECT
T1.C1,
T21.BRANCH AS BRANCH1,
T21.ADDR AS ADDR1,
T22.BRANCH AS BRANCH2,
T22.ADDR AS ADDR2,
T23.BRANCH AS BRANCH3,
T23.ADDR AS ADDR3,
T24.BRANCH AS BRANCH4,
T24.ADDR AS ADDR4,
T25.BRANCH AS BRANCH5,
T25.ADDR AS ADDR5,
T26.BRANCH AS BRANCH6,
T26.ADDR AS ADDR6,
T27.BRANCH AS BRANCH7,
T27.ADDR AS ADDR7,
T28.BRANCH AS BRANCH8,
T28.ADDR AS ADDR8
FROM T1
LEFT OUTER JOIN T2 T21 ON T1.C1 = T21.C1 AND T1.C2 = T21.C2
LEFT OUTER JOIN T2 T22 ON T1.C1 = T22.C1 AND T1.C3 = T22.C2
LEFT OUTER JOIN T2 T23 ON T1.C1 = T23.C1 AND T1.C4 = T23.C2
LEFT OUTER JOIN T2 T24 ON T1.C1 = T24.C1 AND T1.C5 = T24.C2
LEFT OUTER JOIN T2 T25 ON T1.C1 = T25.C1 AND T1.C6 = T25.C2
LEFT OUTER JOIN T2 T26 ON T1.C1 = T26.C1 AND T1.C7 = T26.C2
LEFT OUTER JOIN T2 T27 ON T1.C1 = T27.C1 AND T1.C8 = T27.C2
LEFT OUTER JOIN T2 T28 ON T1.C1 = T28.C1 AND T1.C9 = T28.C2;
对于每个连接,第一个条件都在相同的列上,但第二个条件不同,从T1到T2的同一列都是不同的列。
我已经在SELECT子句中使用OR和多个CASE语句重写了这些多个连接,但尽管成本较低,但执行时间却更长。
对于给定的输出,只能参考表T2 8次?
**预期输入/输出:**x1c 0d1x
1条答案
按热度按时间bnl4lu3b1#
如果每个
C1
值只需要一行,则可以使用条件聚合对JOIN
进行一次透视:对于样本数据,它输出:
| C1|分支1|地址1|分支2|地址2|分支3|地址3|分支4|地址4|支管5|地址5|支管6|地址6|分支7|地址7|分支8|地址8|
| - ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|
| 阿四四四| * 无效 | 无效 | 无效 | 无效 | 无效 | 无效 | 无效 | 无效 *| 液压|联合 Realm |液压|联合 Realm |液压|联合 Realm |液压|联合 Realm |
| A333公路| * 无效 | 无效 | 无效 | 无效 | 无效 | 无效 | 无效 | 无效 | 无效 | 无效 | 无效 | 无效 | 无效 | 无效 | 无效 | 无效 *|
| A111|中国|印度|中国|印度|中国|印度|中国|印度|中国|印度|中国|印度|中国|印度|中国|印度|
| 阿二二二|最大似然|美国|最大似然|美国|最大似然|美国| * 无效 | 无效 | 无效 | 无效 | 无效 | 无效 | 无效 | 无效 *| 最大似然|美国|
fiddle