进行选择后,我正在对数据进行自连接和不同的操作。我不确定是否有更好的方法来编写此查询。你能建议吗?
下面是查询和解释计划输出。
WITH data
AS ( SELECT san.S1FK_C_ID,
san.S1FK_CF_ID,
san.S1FK_A_ID,
san.S1FK_A_TYPE,
san.S1FK_S_TYPE,
san.S1FK_B_FUNC,
AU.AS1FK_A_ID,
AU.AS1FK_B_FUNC,
AU.AS1FK_S_TYPE,
AU.AS1FK_T_CODE,
A2FK_B_ID,
A2FK_NBR,
A2FK_C_CD,
A1FK_B_ID,
A1FK_NBR,
A1FK_C_CD,
AU.R_NAME,
IND
FROM N_RULE cnr,
SAN san,
ACCT_USG AU
WHERE AU.R_NAME = CNR.R_NAME
AND AU.A2FK_C_CD = CNR.C_CD
AND AU.AS1FK_B_FUNC = CNR.B_FUNC
AND AU.AS1FK_A_ID = san.AS1FK_ID || ''
AND AU.AS1FK_B_FUNC = san.AS1FK_B_FUNC
AND AU.AS1FK_S_TYPE = san.AS1FK_S_TYPE
AND AU.AS1FK_T_CODE = san.AS1FK_A_TYPE
AND CNR.FM_CODE = 'SP'
AND san.STATUS = 'A'
AND san.AS1FK_B_FUNC = CNR.B_FUNC
ORDER BY AU.AS1FK_A_ID)
SELECT DISTINCT A.A2FK_C_CD AS C_CD,
-- secondary id's
B.S1FK_C_ID AS C_ID_2,
B.S1FK_CF_ID AS CF_ID_2,
B.S1FK_A_ID AS A_ID_2,
B.S1FK_B_FUNC AS B_FUNC_2,
B.S1FK_S_TYPE AS S_TYPE_2,
B.S1FK_A_TYPE AS A_TYPE_2,
--primary id's
A.S1FK_A_ID AS A_ID_1,
A.S1FK_B_FUNC AS B_FUNC_1,
A.S1FK_S_TYPE AS S_TYPE_1,
A.S1FK_A_TYPE AS A_TYPE_1
FROM data A, --A is the set of primary and standalone id's
data B
--B is the primary and secondary id's
WHERE
B .R_NAME = A.R_NAME
--as join
AND B.AS1FK_B_FUNC = A.AS1FK_B_FUNC
AND B.AS1FK_S_TYPE = A.AS1FK_S_TYPE
AND B.AS1FK_T_CODE = A.AS1FK_T_CODE
--accts join
AND B.A2FK_NBR = A.A2FK_NBR
AND B.A2FK_B_ID = A.A2FK_B_ID
AND B.A2FK_C_CD = A.A2FK_C_CD
AND B.A1FK_NBR = A.A1FK_NBR
AND B.A1FK_B_ID = A.A1FK_B_ID
AND B.A1FK_C_CD = A.A1FK_C_CD
--s fk join
AND B.S1FK_C_ID = A.S1FK_C_ID
AND B.S1FK_CF_ID = A.S1FK_CF_ID
AND B.S1FK_S_TYPE = A.S1FK_S_TYPE
AND B.S1FK_B_FUNC = A.S1FK_B_FUNC
AND B.S1FK_A_TYPE = A.S1FK_A_TYPE
AND ( --join secondary ( N ) and primary id's ( Y ) to primary id's
( 'Y' = A.IND
AND B.IND IN ('N', 'Y') )
OR --join standalone ( ' ' ) id's to themselves
( ' ' = B.IND
AND ' ' = A.IND )
AND B.AS1FK_A_ID = A.AS1FK_A_ID
);
计划:
PLAN_TABLE_OUTPUT
Plan hash value: 3120521488
----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 450 | 18 (17)| 00:00:01 |
| 1 | TEMP TABLE TRANSFORMATION | | | | | |
| 2 | LOAD AS SELECT | SYS_TEMP_0FD9D949F_E879D9BC | | | | |
| 3 | SORT ORDER BY | | 1 | 296 | 12 (9)| 00:00:01 |
| 4 | NESTED LOOPS | | 1 | 296 | 11 (0)| 00:00:01 |
| 5 | NESTED LOOPS | | 7412 | 1889K| 11 (0)| 00:00:01 |
|* 6 | TABLE ACCESS FULL | SAN | 255 | 20910 | 11 (0)| 00:00:01 |
| 7 | TABLE ACCESS BY INDEX ROWID| ACCT_USG | 29 | 5191 | 0 (0)| 00:00:01 |
|* 8 | INDEX RANGE SCAN | ACCT_USG_PK | 1 | | 0 (0)| 00:00:01 |
|* 9 | INDEX UNIQUE SCAN | N_RULE_PK | 1 | 35 | 0 (0)| 00:00:01 |
| 10 | HASH UNIQUE | | 1 | 450 | 6 (34)| 00:00:01 |
|* 11 | HASH JOIN | | 1 | 450 | 5 (20)| 00:00:01 |
| 12 | VIEW | | 1 | 225 | 2 (0)| 00:00:01 |
| 13 | TABLE ACCESS FULL | SYS_TEMP_0FD9D949F_E879D9BC | 1 | 225 | 2 (0)| 00:00:01 |
| 14 | VIEW | | 1 | 225 | 2 (0)| 00:00:01 |
| 15 | TABLE ACCESS FULL | SYS_TEMP_0FD9D949F_E879D9BC | 1 | 225 | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
6 - filter("SAN"."EFF_STATUS_CODE"='A')
8 - access("AU"."AS1FK_A_ID"="SAN"."AS1FK_ID"||'' AND
"AU"."AS1FK_T_CODE"="SAN"."AS1FK_A_TYPE" AND
"AU"."AS1FK_S_TYPE"="SAN"."AS1FK_S_TYPE" AND
"AU"."AS1FK_B_FUNC"="SAN"."AS1FK_B_FUNC")
9 - access("CNR"."FM_CODE"='SP' AND "SAN"."S1FK_C_ID"="CNR"."CLRG_ORG_ID" AND
"SAN"."AS1FK_B_FUNC"="CNR"."B_F_CODE" AND "AU"."A2FK_C_CD"="CNR"."C_CD" AND
"AU"."R_NAME"="CNR"."R_NAME")
filter("AU"."AS1FK_B_FUNC"="CNR"."B_F_CODE")
11 - access("B"."R_NAME"="A"."R_NAME" AND "B"."AS1FK_B_FUNC"="A"."AS1FK_B_FUNC" AND
"B"."AS1FK_S_TYPE"="A"."AS1FK_S_TYPE" AND "B"."AS1FK_T_CODE"="A"."AS1FK_T_CODE"
AND "B"."A2FK_NBR"="A"."A2FK_NBR" AND "B"."A2FK_B_ID"="A"."A2FK_B_ID" AND
"B"."A2FK_C_CD"="A"."A2FK_C_CD" AND "B"."A1FK_NBR"="A"."A1FK_NBR" AND
"B"."A1FK_B_ID"="A"."A1FK_B_ID" AND "B"."A1FK_C_CD"="A"."A1FK_C_CD" AND
"B"."S1FK_C_ID"="A"."S1FK_C_ID" AND "B"."S1FK_CF_ID"="A"."S1FK_CF_ID" AND
"B"."S1FK_S_TYPE"="A"."S1FK_S_TYPE" AND "B"."S1FK_B_FUNC"="A"."S1FK_B_FUNC" AND
"B"."STACO1FK_A_TYPE"="A"."STACO1FK_A_TYPE")
filter("A"."IND"='Y' AND ("B"."IND"='N' OR
"B"."IND"="A"."IND") OR "B"."IND"=' ' AND
"A"."IND"=' ' AND "B"."AS1FK_A_ID"="A"."AS1FK_A_ID" AND
"B"."IND"="A"."IND")
EDIT
~~~~
- 我编辑了上面的 SQL 以删除自连接和不必要的分组。
- 我只基于连接对 primary_secondary 行进行分组。
- 在主要和次要之间,我正在决定应该插入次要的主要帐户。
这给出了相同的结果。我想知道这是否可以进一步改进。
WITH data
AS ( SELECT sanw.STAC01FK_C_ID,
sanw.STAC01FK_CF_ID,
sanw.STAC01FK_A_ID,
sanw.STACO1FK_A_TYPE,
sanw.STAC01FK_S_TYPE,
sanw.STAC01FK_B_FUNC,
BAU.ASAC01FK_A_ID,
BAU.ASAC01FK_B_FUNC,
BAU.ASAC01FK_S_TYPE,
BAU.ASAC01FK_TYPE_CODE,
BAAC02FK_BANK_ID,
BAAC02FK_NBR,
BAAC02FK_CURR_CD,
BAAC01FK_BANK_ID,
BAAC01FK_NBR,
BAAC01FK_CURR_CD,
BAU.R_NAME,
PRIMARY_ACCT_IND
FROM N_RULE cnr,
SAN sanw,
ACCT_USG bau
WHERE BAU.R_NAME = CNR.R_NAME
AND BAU.BAAC02FK_CURR_CD = CNR.C_CD
AND BAU.ASAC01FK_B_FUNC = CNR.B_FUNC_CD
AND BAU.ASAC01FK_A_ID = sanw.ASAC01FK_ID
AND BAU.ASAC01FK_B_FUNC = sanw.ASAC01FK_B_FUNC
AND BAU.ASAC01FK_S_TYPE = sanw.ASAC01FK_S_TYPE
AND BAU.ASAC01FK_TYPE_CODE = sanw.ASAC01FK_A_TYPE
AND CNR.FM_CODE = 'SP'
AND sanw.EFF_STATUS_CODE = 'A'
AND sanw.ASAC01FK_B_FUNC = CNR.B_FUNC_CD),
primary_secondary
AS (SELECT PRIMARY_ACCT_IND,
B.BAAC02FK_CURR_CD AS C_CD,
B.STAC01FK_C_ID AS C_ID_2,
B.STAC01FK_CF_ID AS CF_ID_2,
-- secondary accounts
B.STAC01FK_A_ID AS A_ID_2,
B.STAC01FK_B_FUNC AS B_FUNC_2,
B.STAC01FK_S_TYPE AS S_TYPE_2,
B.STACO1FK_A_TYPE AS A_TYPE_2,
--primary accounts
B.STAC01FK_A_ID AS A_ID_1,
B.STAC01FK_B_FUNC AS B_FUNC_1,
B.STAC01FK_S_TYPE AS S_TYPE_1,
B.STACO1FK_A_TYPE AS A_TYPE_1,
RANK ()
OVER (
PARTITION BY
--bank acct join
B.BAAC02FK_CURR_CD,
--sa join
B.STAC01FK_S_TYPE,
B.STAC01FK_B_FUNC,
B.STACO1FK_A_TYPE,
B.STAC01FK_C_ID,
B.STAC01FK_CF_ID
ORDER BY
PRIMARY_ACCT_IND DESC)
AS d_rank
FROM data B
WHERE B.PRIMARY_ACCT_IND IN ('Y', 'N')),
stand_alone
AS (SELECT B.BAAC02FK_CURR_CD AS C_CD,
B.STAC01FK_C_ID AS C_ID_2,
B.STAC01FK_CF_ID AS CF_ID_2,
-- secondary accounts
B.STAC01FK_A_ID AS A_ID_2,
B.STAC01FK_B_FUNC AS B_FUNC_2,
B.STAC01FK_S_TYPE AS S_TYPE_2,
B.STACO1FK_A_TYPE AS A_TYPE_2,
--primary accounts
B.STAC01FK_A_ID AS A_ID_1,
B.STAC01FK_B_FUNC AS B_FUNC_1,
B.STAC01FK_S_TYPE AS S_TYPE_1,
B.STACO1FK_A_TYPE AS A_TYPE_1
FROM data B
WHERE B.PRIMARY_ACCT_IND = ' '),
PRIMARY
AS (SELECT C_CD,
C_ID_2,
CF_ID_2,
-- secondary accounts
A_ID_2,
B_FUNC_2,
S_TYPE_2,
A_TYPE_2,
--primary accounts
A_ID_1,
B_FUNC_1,
S_TYPE_1,
A_TYPE_1
FROM primary_secondary
WHERE D_RANK = 1),
SECONDARY
AS (SELECT ps.C_CD,
ps.C_ID_2,
ps.CF_ID_2,
-- secondary accounts
ps.A_ID_2,
ps.B_FUNC_2,
ps.S_TYPE_2,
ps.A_TYPE_2,
--primary accounts
p.A_ID_1,
p.B_FUNC_1,
p.S_TYPE_1,
p.A_TYPE_1
FROM primary_secondary ps, primary p
WHERE ps.D_RANK <> 1
AND ps.C_CD = p.C_CD
AND ps.C_ID_2 = p.C_ID_2
AND ps.CF_ID_2 = p.CF_ID_2
-- secondarary accounts
AND ps.B_FUNC_2 = p.B_FUNC_2
AND ps.S_TYPE_2 = p.S_TYPE_2
AND ps.A_TYPE_2 = p.A_TYPE_2)
SELECT * FROM secondary
UNION ALL
SELECT * FROM primary
UNION ALL
SELECT * FROM stand_alone
计划:
Plan hash value: 3159296610
----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 33 | 3421 | 9 (56)| 00:00:01 |
| 1 | TEMP TABLE TRANSFORMATION | | | | | |
| 2 | LOAD AS SELECT | SYS_TEMP_0FD9DBAF1_9261CF31 | | | | |
|* 3 | HASH JOIN | | 11 | 3058 | 119 (1)| 00:00:02 |
|* 4 | HASH JOIN | | 96 | 18816 | 104 (1)| 00:00:02 |
|* 5 | INDEX RANGE SCAN | CNR_PK | 61 | 1769 | 1 (0)| 00:00:01 |
| 6 | TABLE ACCESS FULL | ACCT_USG | 8244 | 1344K| 102 (0)| 00:00:02 |
|* 7 | TABLE ACCESS FULL | SAN | 1444 | 115K| 15 (0)| 00:00:01 |
| 8 | LOAD AS SELECT | SYS_TEMP_0FD9DBAF2_9261CF31 | | | | |
| 9 | WINDOW SORT | | 11 | 594 | 3 (34)| 00:00:01 |
|* 10 | VIEW | | 11 | 594 | 2 (0)| 00:00:01 |
| 11 | TABLE ACCESS FULL | SYS_TEMP_0FD9DBAF1_9261CF31 | 11 | 2343 | 2 (0)| 00:00:01 |
| 12 | LOAD AS SELECT | SYS_TEMP_0FD9DBAF3_9261CF31 | | | | |
|* 13 | VIEW | | 11 | 1089 | 2 (0)| 00:00:01 |
| 14 | TABLE ACCESS FULL | SYS_TEMP_0FD9DBAF2_9261CF31 | 11 | 682 | 2 (0)| 00:00:01 |
| 15 | UNION-ALL | | | | | |
|* 16 | HASH JOIN | | 11 | 1672 | 5 (20)| 00:00:01 |
|* 17 | VIEW | | 11 | 792 | 2 (0)| 00:00:01 |
| 18 | TABLE ACCESS FULL | SYS_TEMP_0FD9DBAF2_9261CF31 | 11 | 682 | 2 (0)| 00:00:01 |
| 19 | VIEW | | 11 | 880 | 2 (0)| 00:00:01 |
| 20 | TABLE ACCESS FULL | SYS_TEMP_0FD9DBAF3_9261CF31 | 11 | 946 | 2 (0)| 00:00:01 |
| 21 | VIEW | | 11 | 1067 | 2 (0)| 00:00:01 |
| 22 | TABLE ACCESS FULL | SYS_TEMP_0FD9DBAF3_9261CF31 | 11 | 946 | 2 (0)| 00:00:01 |
|* 23 | VIEW | | 11 | 682 | 2 (0)| 00:00:01 |
| 24 | TABLE ACCESS FULL | SYS_TEMP_0FD9DBAF1_9261CF31 | 11 | 2343 | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("BAU"."ASAC01FK_A_ID"="SANW"."ASAC01FK_ID"||'' AND
"BAU"."ASAC01FK_B_FUNC"="SANW"."ASAC01FK_B_FUNC" AND
"BAU"."ASAC01FK_S_TYPE"="SANW"."ASAC01FK_S_TYPE" AND
"BAU"."ASAC01FK_TYPE_CODE"="SANW"."ASAC01FK_A_TYPE" AND
"SANW"."ASAC01FK_B_FUNC"="CNR"."B_FUNC_CD")
4 - access("BAU"."R_NAME"="CNR"."R_NAME" AND
"BAU"."BAAC02FK_CURR_CD"="CNR"."C_CD" AND
"BAU"."ASAC01FK_B_FUNC"="CNR"."B_FUNC_CD")
5 - access("CNR"."FM_CODE"='SP')
7 - filter("SANW"."EFF_STATUS_CODE"='A')
10 - filter("B"."PRIMARY_ACCT_IND"='N' OR "B"."PRIMARY_ACCT_IND"='Y')
13 - filter("D_RANK"=1)
16 - access("PS"."C_CD"="P"."C_CD" AND "PS"."C_ID_2"="P"."C_ID_2" AND
"PS"."CF_ID_2"="P"."CF_ID_2" AND "PS"."B_FUNC_2"="P"."B_FUNC_2" AND
"PS"."S_TYPE_2"="P"."S_TYPE_2" AND "PS"."A_TYPE_2"="P"."A_TYPE_2")
17 - filter("PS"."D_RANK"<>1)
23 - filter("B"."PRIMARY_ACCT_IND"=' ')