如何在sqlplus中编写包含多个表的递归子查询来跟踪节点?

如何在sqlplus中编写包含多个表的递归子查询来跟踪节点?,sql,oracle,common-table-expression,recursive-query,Sql,Oracle,Common Table Expression,Recursive Query,我试图创建一个报告,将电路上的负载映射到各自的电源变压器 所有设备都在单独的表中,并在数据库中互连:负载、开关、线路、电线、变压器 为了简单起见,我将展示一个示例,其中负载仅通过开关直接连接到变压器: 负载表: LoadNumber, SectionNumber, BusNumber 100 54 3000 开关表: SwitchNumber, FromSectionNumber, ToSectionNumber, State, BusNumber 1

我试图创建一个报告,将电路上的负载映射到各自的电源变压器

所有设备都在单独的表中,并在数据库中互连:负载、开关、线路、电线、变压器

为了简单起见,我将展示一个示例,其中负载仅通过开关直接连接到变压器:

负载表:

LoadNumber, SectionNumber, BusNumber
100         54             3000
开关表:

SwitchNumber, FromSectionNumber, ToSectionNumber, State, BusNumber
1             54                 105              Closed 3000
2             105                106              Closed 3000
3             106                500              Open   3000
4             105                999              Closed 3000
5             999                700              Closed 3000
变压器表:

TransformerNumber, FromSectionNumber, ToSectionNumber, FromBus, ToBus
5000               800                700              2000     3000
5001               801                701              2000     3000
在上述示例中,变压器5000通过表中的开关连接至负载100,并通电,因为有一个闭合电路闭合开关将变压器和负载连接在一起

我正在尝试编写一个查询,该查询可以生成类似以下内容的输出:

LoadNumber, TransformerNumber
100         5000
表示负载100由变压器5000供电

我能够使用1个表开关成功地获得一个查询,以找到它们链接到的转换器,但我对如何涉及所有表以获得网络的完整视图有点迷茫

到目前为止,我得到的是:

WITH T3 AS
(SELECT SWITCHNAME, SWITCHNUMBER, PSEUDOSWITCH, FROMSECTIONNUMBER, TOSECTIONNUMBER, NORMALSWITCHINGDEVICESTATE, BUSNUMBER
FROM SWITCHINGDEVICE
WHERE UPPER(NORMALSWITCHINGDEVICESTATE) = 'CLOSED'
AND BUSNUMBER = 3484),
T2 AS
(SELECT TRANSFORMERNUMBER, TRANSFORMERNAME, FROMSECTIONNUMBER, TOSECTIONNUMBER, FROMBUSNUMBER, TOBUSNUMBER
FROM TRANSFORMER
WHERE TOBUSNUMBER = 3484),
T4 AS
(SELECT DEVICENUMBER, DEVICENAME, FROMSECTIONNUMBER, TOSECTIONNUMBER, FROMBUSREF, TOBUSREF
FROM PSA_SERIESREACTIVEDEVICE
WHERE TOBUSREF = 3484),
T5 AS
(SELECT LINENUMBER, LINENAME, FROMSECTIONNUMBER, TOSECTIONNUMBER, FROMBUSNUMBER, TOBUSNUMBER
FROM LINE
WHERE TOBUSNUMBER = 3484 AND FROMBUSNUMBER = 3484),
T1 AS
(SELECT A.BUSNUMBER, A.LOADNUMBER, A.LOADNAME, B.TRANSFORMERNUMBER, B.TRANSFORMERNAME
FROM LOADDEFINITION A, TRANSFORMER B
WHERE A.LOADNUMBER = 5572
AND A.BUSNUMBER = B.TOBUSNUMBER
---TEST LOAD
UNION ALL
SELECT T1.BUSNUMBER, T1.LOADNUMBER, T1.LOADNAME, T2.TRANSFORMERNUMBER, T2.TRANSFORMERNAME
FROM LOADDEFINITION T1, TRANSFORMER T2, SWITCHINGDEVICE T3, PSA_SERIESREACTIVEDEVICE T4, LINE T5, SWITCHINGDEVICE T6
WHERE
T1.LOADNUMBER = 5572 AND T1.BUSNUMBER = 3484
AND T2.TOBUSNUMBER = T1.BUSNUMBER
AND T3.BUSNUMBER = T1.BUSNUMBER
AND T4.TOBUSREF = T1.BUSNUMBER
AND T5.TOBUSNUMBER = T1.BUSNUMBER
AND T5.FROMBUSNUMBER = T5.TOBUSNUMBER
AND T3.BUSNUMBER = T2.TOBUSNUMBER
AND T4.TOBUSREF = T2.TOBUSNUMBER
AND T5.TOBUSNUMBER = T2.TOBUSNUMBER
AND T3.BUSNUMBER = T4.TOBUSREF
AND T5.TOBUSNUMBER = T3.BUSNUMBER
AND T5.TOBUSNUMBER = T4.TOBUSREF
AND T6.BUSNUMBER = T1.BUSNUMBER
---take into consideration downstream loops
AND ((T1.SECTIONNUMBER = T3.TOSECTIONNUMBER AND T1.SECTIONNUMBER = T6.TOSECTIONNUMBER)
    OR
     (T1.SECTIONNUMBER = T3.FROMSECTIONNUMBER AND T1.SECTIONNUMBER = T6.FROMSECTIONNUMBER))
AND (T3.FROMSECTIONNUMBER = T2.TOSECTIONNUMBER)
AND (T3.FROMSECTIONNUMBER = T6.TOSECTIONNUMBER)
AND T6.NORMALSWITCHINGDEVICESTATE = T3.NORMALSWITCHINGDEVICESTATE
)
SELECT T1.BUSNUMBER, T1.LOADNUMBER, T1.LOADNAME, T2.TRANSFORMERNUMBER, T2.TRANSFORMERNAME FROM T1, T2
但是,由于我硬编码了一个负载,所以没有像我预期的那样返回1个结果,而是返回了一个显示所有变压器的列表

用示例数据表示,结果如下所示:

LoadNumber, TransformerNumber
100         5000
100         5001
我已经玩了一段时间了,不确定这个查询的哪一部分出错了

编辑:

如果我想使用示例数据集编写一个查询以获得所需的结果,那么该如何实现呢


逻辑如下:选择loadnumber,transformernumber,其中load通过闭合开关设备与变压器进行带电连接?

在您的简化示例中,我开始使用您的真实表名,但这是原始数据,您可以通过多个交换机获得所有路由:

with rcte (rootsectionnumber, fromsectionnumber, tosectionnumber) as (
  select fromsectionnumber, fromsectionnumber, tosectionnumber
  from switchingdevice
  where normalswitchingdevicestate = 'CLOSED'
  union all
  select r.rootsectionnumber, sd.fromsectionnumber, sd.tosectionnumber
  from rcte r
  join switchingdevice sd on sd.fromsectionnumber = r.tosectionnumber
)
select rootsectionnumber, tosectionnumber from rcte;

ROOTSECTIONNUMBER TOSECTIONNUMBER
----------------- ---------------
               54             105
              105             106
              105             999
              999             700
               54             106
              105             500
               54             999
              105             700
               54             500
               54             700
其中一个具有从第54段到第700段的端到端路线;然后您可以将其连接到负载定义:

with rcte (rootsectionnumber, fromsectionnumber, tosectionnumber) as (
  select fromsectionnumber, fromsectionnumber, tosectionnumber
  from switchingdevice
  where normalswitchingdevicestate = 'CLOSED'
  union all
  select r.rootsectionnumber, sd.fromsectionnumber, sd.tosectionnumber
  from rcte r
  join switchingdevice sd on sd.fromsectionnumber = r.tosectionnumber
)
select ld.loadnumber, t.transformernumber
from loaddefinition ld
join rcte r on r.rootsectionnumber = ld.sectionnumber
join transformer t on t.tosectionnumber = r.tosectionnumber
where ld.loadnumber = 100;

LOADNUMBER TRANSFORMERNUMBER
---------- -----------------
       100              5000
或者,如果您需要根据对更大查询的简要了解,在逻辑中包括总线号…:

with rcte (rootsectionnumber, busnumber, fromsectionnumber, tosectionnumber) as (
  select fromsectionnumber, busnumber, fromsectionnumber, tosectionnumber
  from switchingdevice
  where normalswitchingdevicestate = 'CLOSED'
  union all
  select r.rootsectionnumber, r.busnumber, sd.fromsectionnumber, sd.tosectionnumber
  from rcte r
  join switchingdevice sd on sd.fromsectionnumber = r.tosectionnumber
  and sd.busnumber = r.busnumber
)
select ld.loadnumber, t.transformernumber
from loaddefinition ld
join rcte r on r.rootsectionnumber = ld.sectionnumber
and r.busnumber = ld.busnumber
join transformer t on t.tosectionnumber = r.tosectionnumber
and t.tobusnumber = r.busnumber
where ld.loadnumber = 100;

LOADNUMBER TRANSFORMERNUMBER
---------- -----------------
       100              5000

添加其他表显然会使事情变得复杂一些,但还不清楚它们之间的关系。

我非常感谢您抽出时间来检查我的工作,我认为您向我展示的内容是我应该如何构造查询的一个很好的起点,我将采用您提供的内容并尝试使用它,希望能得到期望的结果,并在我找到答案后更新问题和解决方案。我已把你的回答标为已接受。谢谢一个问题是,为了从该查询中要考虑的其他表映射节点,是否应在RTCE定义中沿交换设备连接所有其他表?我认为每个表都需要单独定义,但根据您编写它的方式,我认为可以将所有表合并到一个定义中。我来试一试。你的最终解决方案可能对未来的访问者没有用处。但是,如果您试图调整它以包括其他表,但无法使其正常工作,那么您可以使用所有表和场景的示例数据提出一个新问题。从这个问题的尝试中有点难以解读*8-@benchwang-这取决于他们之间的关系。如果你反复地从一个线路到另一个线路到另一个线路到另一个线路,而不是从一个线路到一系列的变压器,这可能会变得复杂。同样,我担心这取决于细节。您可以使用SQL做很多事情,通常情况下,对于不可能的事情,应该只使用PL/SQL。这听起来很复杂,但根据你所说的,这是可行的——也许递归和out连接的组合可以做到,但恐怕现在还不能确定。