具有某些连接的分层查询
Hierarchical query with some joins
我正在努力编写一个执行查询,该查询将包含来自一个子 select 的数据,并根据第一个子 table 的行分层检索来自另一个 table 的数据=56=].
因此,我通过连接从多个 table 中检索了一些数据,最终归结为以下内容:
CREATE TABLE TBL1 (UUID, MiscData, KeyToLookup, ConditionClause ) AS
SELECT 13, 'ATM', 12345, null FROM DUAL UNION ALL
SELECT 447, 'Balance Inquiry', 67890, 'BALANCE_INQUIRY_FEE' FROM DUAL UNION ALL
SELECT 789, 'Credit', 22321, 'CREDIT_FEE' FROM DUAL;
现在,我有另一个 table 存储费用的层次结构:
CREATE TABLE TBL2 ( TariffDomainID, FeeType, UpperTariffDomainID, ID ) AS
SELECT 1543, 'WHATEVER_FEE', 154, 1 FROM DUAL UNION ALL
SELECT 1543, 'BALANCE_INQUIRY_FEE', 154, 2 FROM DUAL UNION ALL
SELECT 154, 'SMTHELSE_FEE', 15, 3 FROM DUAL UNION ALL
SELECT 154, 'CREDIT_FEE', 15, 4 FROM DUAL UNION ALL
SELECT 15, 'BALANCE_INQUIRY_FEE', null, 5 FROM DUAL;
并且有一种方法可以将第一个 select 连接到第二个 table 层次结构中的最低行,连接很少,但最终是这样的:
CREATE TABLE TBL3 ( ID, FirstTblKey, SecondTblKey ) AS
SELECT 1, 67890, 1543 FROM DUAL UNION ALL
SELECT 2, 22321, 1543 FROM DUAL;
重要的一点是,不能保证按照 TBL3
的指示,在第二个 table 中直接与此 KeyToLookup
排成一行。
例如。在上面的例子中:
行 TBL1.UUID=789
通过 TBL3
link 编辑到 TBL2
行 TariffDomainID=1543
,
但是 TBL2
中没有包含 TariffDomainID=1543
和 FeeType=CREDIT_FEE
;
的行
但是 TBL2
包含一个 link 到相同的 table 但更高级别 UpperTariffDomainID=154
,
在 TBL2
和 FeeType=CREDIT_FEE
.
中 是 一行
最后,我需要将 TBL1
中的信息与 TBL2
中此键的所有出现按层次结构连接起来,按层次结构的深度编号。
所以我希望得到这个:
| UUID | MiscData | KeyToLookup | ConditionClause | TariffDomainIDWithPresence | Depth |
|------|-----------------|-------------|---------------------|----------------------------|-------|
| 13 | ATM | 12345 | null | null | null |
| 447 | Balance Inquiry | 67890 | BALANCE_INQUIRY_FEE | 1543 | 1 |
| 447 | Balance Inquiry | 67890 | BALANCE_INQUIRY_FEE | 15 | 3 |
| 789 | Credit | 22321 | CREDIT_FEE | 154 | 2 |
谁能教我如何进行这样的分层查询?
您可以使用连接到其他两个表的分层查询:
SELECT DISTINCT
t1.uuid,
t1.miscdata,
t1.keytolookup,
t1.conditionclause,
t2.tariffdomainid,
t2.depth
FROM tbl1 t1
LEFT OUTER JOIN tbl3 t3
ON ( t1.keytolookup = t3.firsttblkey )
OUTER APPLY (
SELECT tariffdomainid,
LEVEL AS depth
FROM tbl2 t2
WHERE t2.tariffdomainid = t3.secondtblkey
START WITH
t2.feetype = t1.conditionclause
CONNECT BY
PRIOR TariffDomainID = UpperTariffDomainID
) t2
ORDER BY
uuid,
depth
其中,对于示例数据,输出:
UUID | MISCDATA | KEYTOLOOKUP | CONDITIONCLAUSE | TARIFFDOMAINID | DEPTH
---: | :-------------- | ----------: | :------------------ | -------------: | ----:
13 | ATM | 12345 | null | null | null
447 | Balance Inquiry | 67890 | BALANCE_INQUIRY_FEE | 1543 | 1
447 | Balance Inquiry | 67890 | BALANCE_INQUIRY_FEE | 1543 | 3
789 | Credit | 22321 | CREDIT_FEE | 1543 | 2
(注意:你需要DISTINCT
,因为TBL2
中有多个1543和154条目,所以分层查询可以采用多条路径从头到尾结束条件。如果您的实际数据没有这些重复项,那么您应该能够删除 DISTINCT
子句。)
db<>fiddle here
我正在努力编写一个执行查询,该查询将包含来自一个子 select 的数据,并根据第一个子 table 的行分层检索来自另一个 table 的数据=56=].
因此,我通过连接从多个 table 中检索了一些数据,最终归结为以下内容:
CREATE TABLE TBL1 (UUID, MiscData, KeyToLookup, ConditionClause ) AS
SELECT 13, 'ATM', 12345, null FROM DUAL UNION ALL
SELECT 447, 'Balance Inquiry', 67890, 'BALANCE_INQUIRY_FEE' FROM DUAL UNION ALL
SELECT 789, 'Credit', 22321, 'CREDIT_FEE' FROM DUAL;
现在,我有另一个 table 存储费用的层次结构:
CREATE TABLE TBL2 ( TariffDomainID, FeeType, UpperTariffDomainID, ID ) AS
SELECT 1543, 'WHATEVER_FEE', 154, 1 FROM DUAL UNION ALL
SELECT 1543, 'BALANCE_INQUIRY_FEE', 154, 2 FROM DUAL UNION ALL
SELECT 154, 'SMTHELSE_FEE', 15, 3 FROM DUAL UNION ALL
SELECT 154, 'CREDIT_FEE', 15, 4 FROM DUAL UNION ALL
SELECT 15, 'BALANCE_INQUIRY_FEE', null, 5 FROM DUAL;
并且有一种方法可以将第一个 select 连接到第二个 table 层次结构中的最低行,连接很少,但最终是这样的:
CREATE TABLE TBL3 ( ID, FirstTblKey, SecondTblKey ) AS
SELECT 1, 67890, 1543 FROM DUAL UNION ALL
SELECT 2, 22321, 1543 FROM DUAL;
重要的一点是,不能保证按照 TBL3
的指示,在第二个 table 中直接与此 KeyToLookup
排成一行。
例如。在上面的例子中:
行 TBL1.UUID=789
通过 TBL3
link 编辑到 TBL2
行 TariffDomainID=1543
,
但是 TBL2
中没有包含 TariffDomainID=1543
和 FeeType=CREDIT_FEE
;
但是 TBL2
包含一个 link 到相同的 table 但更高级别 UpperTariffDomainID=154
,
在 TBL2
和 FeeType=CREDIT_FEE
.
最后,我需要将 TBL1
中的信息与 TBL2
中此键的所有出现按层次结构连接起来,按层次结构的深度编号。
所以我希望得到这个:
| UUID | MiscData | KeyToLookup | ConditionClause | TariffDomainIDWithPresence | Depth |
|------|-----------------|-------------|---------------------|----------------------------|-------|
| 13 | ATM | 12345 | null | null | null |
| 447 | Balance Inquiry | 67890 | BALANCE_INQUIRY_FEE | 1543 | 1 |
| 447 | Balance Inquiry | 67890 | BALANCE_INQUIRY_FEE | 15 | 3 |
| 789 | Credit | 22321 | CREDIT_FEE | 154 | 2 |
谁能教我如何进行这样的分层查询?
您可以使用连接到其他两个表的分层查询:
SELECT DISTINCT
t1.uuid,
t1.miscdata,
t1.keytolookup,
t1.conditionclause,
t2.tariffdomainid,
t2.depth
FROM tbl1 t1
LEFT OUTER JOIN tbl3 t3
ON ( t1.keytolookup = t3.firsttblkey )
OUTER APPLY (
SELECT tariffdomainid,
LEVEL AS depth
FROM tbl2 t2
WHERE t2.tariffdomainid = t3.secondtblkey
START WITH
t2.feetype = t1.conditionclause
CONNECT BY
PRIOR TariffDomainID = UpperTariffDomainID
) t2
ORDER BY
uuid,
depth
其中,对于示例数据,输出:
UUID | MISCDATA | KEYTOLOOKUP | CONDITIONCLAUSE | TARIFFDOMAINID | DEPTH ---: | :-------------- | ----------: | :------------------ | -------------: | ----: 13 | ATM | 12345 | null | null | null 447 | Balance Inquiry | 67890 | BALANCE_INQUIRY_FEE | 1543 | 1 447 | Balance Inquiry | 67890 | BALANCE_INQUIRY_FEE | 1543 | 3 789 | Credit | 22321 | CREDIT_FEE | 1543 | 2
(注意:你需要DISTINCT
,因为TBL2
中有多个1543和154条目,所以分层查询可以采用多条路径从头到尾结束条件。如果您的实际数据没有这些重复项,那么您应该能够删除 DISTINCT
子句。)
db<>fiddle here