查询以获取给定 parent id 的 child 条记录
Query to get child records of given parent id
我有一个查询要从 Table2 中查找 child 数据,该数据具有在其他 table 中定义的分层数据,即 oracle 中的 TABLE1。
表 1
ID, CHILD_ID, PARENT_ID
1, 1
2, 2, 1
3, 3, 2
4, 4, 3
5, 5, 4
6, 6, 4
7, 7, 4
8, 8, 5
9, 9, 5
表 2
NAME,AGE,ID
JJ,22,1
XX,19,2
YY,20,3
KK,21,4
PP,18,5
CC,19,6
DD,22,7
SS,44,8
QQ,33,9
当我查询 ID 7 时,输出应该
NAME,AGE,ID
DD,22,7
因为没有child of 7
当我查询 5 时,它应该显示如下,因为 8 和 9 是 child of 5
NAME,AGE,ID
PP,18,5
SS,44,8
QQ,33,9
请建议,在此先感谢
您可以使用类似这样的查询来找到合适的 children。只需将您在 CONNECT_BY_ROOT (t1.id) = 5
子句中搜索的 ID 从 5 更改为任何 ID,它就会按预期工作。
SELECT t2.name, t2.age, t1.id
FROM table1 t1, table2 t2
WHERE t1.id = t2.id AND CONNECT_BY_ROOT (t1.id) = 5
CONNECT BY PRIOR t1.id = t1.parent_id;
您可以执行类似以下操作来处理一般情况(即不仅会得到 parents 和 children,而且可能会得到 children-of-children 等等)。
with thevalues as
(
SELECT child, parent
FROM table1
START WITH parent=4
CONNECT BY PRIOR child = parent
)
SELECT *
FROM table2
WHERE id IN (SELECT child FROM thevalues UNION ALL SELECT parent FROM thevalues)
其中 parent=4
定义起始记录。 Connect By 用于这些分层查询。
尽管以上内容也适用于您示例中的简单情况,但如果您不关心 children-of-children,您可能更喜欢
SELECT *
FROM table2
WHERE id=4
UNION ALL
SELECT *
FROM table2
WHERE id IN
(
SELECT child
FROM table1
WHERE parent=4
)
请注意,我在本例中的两个地方硬编码了 4。
如果您只需要立即 children,那么 exists
子查询就足够了:
select t2.*
from table2 t2
where exists (
select 1 from table1 t1 where t1.child_id = t2.id and 5 in (t1.child_id, t1.parent_id)
)
或者:
select t2.*
from table2 t2
where t2.id = 5 or exists (
select 1 from table1 t1 where t1.child_id = t2.id and t1.parent_id = 5
)
另一方面,如果您想要所有 children,而不考虑它们的级别,那么我建议使用递归查询:
with cte (child_id, parent_id) as (
select child_id, parent_id from table1 where child_id = 5
union all
select t1.child_id, t1.parent_id
from cte c
inner join table1 t1 on t1.parent_id = c.child_id
)
select t2.*
from table2 t2
where exists (select 1 from cte c where c.child_id = t2.id)
我有一个查询要从 Table2 中查找 child 数据,该数据具有在其他 table 中定义的分层数据,即 oracle 中的 TABLE1。
表 1
ID, CHILD_ID, PARENT_ID
1, 1
2, 2, 1
3, 3, 2
4, 4, 3
5, 5, 4
6, 6, 4
7, 7, 4
8, 8, 5
9, 9, 5
表 2
NAME,AGE,ID
JJ,22,1
XX,19,2
YY,20,3
KK,21,4
PP,18,5
CC,19,6
DD,22,7
SS,44,8
QQ,33,9
当我查询 ID 7 时,输出应该
NAME,AGE,ID
DD,22,7
因为没有child of 7
当我查询 5 时,它应该显示如下,因为 8 和 9 是 child of 5
NAME,AGE,ID
PP,18,5
SS,44,8
QQ,33,9
请建议,在此先感谢
您可以使用类似这样的查询来找到合适的 children。只需将您在 CONNECT_BY_ROOT (t1.id) = 5
子句中搜索的 ID 从 5 更改为任何 ID,它就会按预期工作。
SELECT t2.name, t2.age, t1.id
FROM table1 t1, table2 t2
WHERE t1.id = t2.id AND CONNECT_BY_ROOT (t1.id) = 5
CONNECT BY PRIOR t1.id = t1.parent_id;
您可以执行类似以下操作来处理一般情况(即不仅会得到 parents 和 children,而且可能会得到 children-of-children 等等)。
with thevalues as
(
SELECT child, parent
FROM table1
START WITH parent=4
CONNECT BY PRIOR child = parent
)
SELECT *
FROM table2
WHERE id IN (SELECT child FROM thevalues UNION ALL SELECT parent FROM thevalues)
其中 parent=4
定义起始记录。 Connect By 用于这些分层查询。
尽管以上内容也适用于您示例中的简单情况,但如果您不关心 children-of-children,您可能更喜欢
SELECT *
FROM table2
WHERE id=4
UNION ALL
SELECT *
FROM table2
WHERE id IN
(
SELECT child
FROM table1
WHERE parent=4
)
请注意,我在本例中的两个地方硬编码了 4。
如果您只需要立即 children,那么 exists
子查询就足够了:
select t2.*
from table2 t2
where exists (
select 1 from table1 t1 where t1.child_id = t2.id and 5 in (t1.child_id, t1.parent_id)
)
或者:
select t2.*
from table2 t2
where t2.id = 5 or exists (
select 1 from table1 t1 where t1.child_id = t2.id and t1.parent_id = 5
)
另一方面,如果您想要所有 children,而不考虑它们的级别,那么我建议使用递归查询:
with cte (child_id, parent_id) as (
select child_id, parent_id from table1 where child_id = 5
union all
select t1.child_id, t1.parent_id
from cte c
inner join table1 t1 on t1.parent_id = c.child_id
)
select t2.*
from table2 t2
where exists (select 1 from cte c where c.child_id = t2.id)