【问题标题】:Connect by prior get parents and children通过事先获取父母和孩子联系
【发布时间】:2018-01-29 13:07:43
【问题描述】:

我正在处理一个使用先验连接的查询。 我编写了一个查询来检索实体的所有子项。我想要的是检索子行和父行。

这是我的 SQL:

Select *
From myTable tab
Connect By Prior tab.id= tab.child_id
Start With tab.id= 2;

我怎样才能找回父母? 谢谢。

【问题讨论】:

标签: sql oracle connect-by


【解决方案1】:

使用UNION ALL 组合一个查询来获取孩子,另一个查询来获取祖先。

SQL Fiddle

Oracle 11g R2 架构设置

CREATE TABLE myTable ( id, child_id ) AS
SELECT 0, 1 FROM DUAL UNION ALL
SELECT 1, 2 FROM DUAL UNION ALL
SELECT 2, 3 FROM DUAL UNION ALL
SELECT 3, 4 FROM DUAL UNION ALL
SELECT 4, 5 FROM DUAL UNION ALL
SELECT 3, 6 FROM DUAL UNION ALL
SELECT 0, 7 FROM DUAL UNION ALL
SELECT 1, 8 FROM DUAL;

查询 1

SELECT *                        -- Child Rows
FROM   mytable
START WITH id = 2
CONNECT BY PRIOR child_id = id
UNION ALL
SELECT *                        -- Ancestor Rows
FROM   mytable
START WITH child_id = 2
CONNECT BY PRIOR id = child_id

Results

| ID | CHILD_ID |
|----|----------|
|  2 |        3 |
|  3 |        4 |
|  4 |        5 |
|  3 |        6 |
|  1 |        2 |
|  0 |        1 |

【讨论】:

  • 感谢您的回复,但它必须计算行数。我可以将 UNION ALL 与 COUNT 一起使用吗?
  • 是的 - SELECT COUNT(*) FROM ( include_union_all_query_here )
  • 感谢您的回复,我会测试一下。
  • 我必须在第二个查询中添加一个条件以排除起始行以避免重复。但它似乎工作!非常感谢。
  • 第二个查询有START WITH child_id(与第一个查询不同),不应包含相同的行。
【解决方案2】:

如果您使用的是 11gR2 或更高版本,分层查询的另一种方法是 recursive subquery factoring

with rcte (id, child_id, some_other_col) as (
  select id, child_id, some_other_col -- whichever columns you're interested in
  from myTable
  where id = 2
  union all
  select t.id, t.child_id, t.some_other_col  -- whichever columns you're interested in
  from rcte r
  join myTable t
  on t.id = r.child_id -- match parents
  or t.child_id = r.id -- match children
)
cycle id set is_cycle to 1 default 0
select id, child_id, some_other_col  -- whichever columns you're interested in
from rcte
where is_cycle = 0;

锚成员找到您的初始目标行。然后递归成员查找到目前为止找到的每一行的父级个子级。

最终查询可以获取你想要的任何列,进行聚合等。

(当然,可能值得用真实数据测试这两种方法,看看是否存在性能差异)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 2018-01-29
    • 1970-01-01
    • 2018-01-15
    • 1970-01-01
    • 2017-10-25
    • 1970-01-01
    相关资源
    最近更新 更多