【问题标题】:Hierarchical query with some joins带有一些连接的分层查询
【发布时间】:2023-04-07 10:59:02
【问题描述】:

我正在努力编写一个执行查询,该查询将包含来自一个子选择的数据,以及基于第一个子选择的行从另一个表中分层检索的数据。

所以,我通过连接从多个表中检索到一些数据,最终归结为以下内容:

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;

现在,我有另一个存储费用层次结构的表:

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;

还有一种方法可以将第一个选择链接到第二个表层次结构中的最低行,连接很少,但最终是这样的:

CREATE TABLE TBL3 ( ID, FirstTblKey, SecondTblKey ) AS
SELECT 1, 67890, 1543 FROM DUAL UNION ALL
SELECT 2, 22321, 1543 FROM DUAL;

重要的一点是,不能保证按照TBL3 的指示,在第二个表中直接有一行带有此KeyToLookup 的行。 例如。在上面的例子中:

TBL1.UUID=789 行通过TBL3 链接到TBL2TariffDomainID=1543
TBL2 中没有行,TariffDomainID=1543FeeType=CREDIT_FEE

但是TBL2 包含指向同一表但更高级别的链接,UpperTariffDomainID=154
TBL2 中有一行,TariffDomainID=154FeeType=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   |

谁能教我如何进行这样的分层查询?

【问题讨论】:

    标签: sql oracle connect-by


    【解决方案1】:

    您可以使用连接到其他两个表的分层查询:

    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 |杂项数据 |键查找 |条件条款 |关税领域 |深度 ---: | :---------------- | ----------: | :----------------- | -------------: | ----: 13 |自动柜员机 | 12345 | | | 第447章余额查询 | 67890 | BALANCE_INQUIRY_FEE |第1543章1 第447章余额查询 | 67890 | BALANCE_INQUIRY_FEE |第1543章3 第789章信用 | 22321 |信用费 |第1543章2

    (注意:您需要 DISTINCT,因为在 TBL2 中有多个 1543 和 154 条目,因此分层查询可以采用多个路径从开始到结束条件。如果您的实际数据确实如此如果没有这些重复项,那么您应该可以删除 DISTINCT 子句。)

    db小提琴here

    【讨论】:

    • 谢谢,我正在尝试验证建议的解决方案,但由于查询未在合理的时间内完成,因此必须关闭某些内容。我会在周日重返工作岗位后回来。
    • 我能够使用您展示的技术调整脚本以在我所拥有的真实场景中使用。非常感谢您的帮助!
    猜你喜欢
    • 2020-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-20
    • 1970-01-01
    • 1970-01-01
    • 2014-12-01
    • 2016-06-11
    相关资源
    最近更新 更多