下面的查询花费约一分钟。我相信表现不佳是由两个“IN(SELECT ...”的条款引起的。我有一个地方可以通过term_relationship表连接到另一个术语表。这些关系可以是递归的,例如,狗是一种类型的哺乳动物,哺乳动物是动物类型的,这递归可以是任何深度,但可能不会超过〜10级。我试图选择具有A型(潜在递归)关系的所有方面,并有一个(潜在的递归)的关系与B型。我认为,随着限制替换两个“IN(SELECT ...”的条款对外部查询会提高性能,但无法弄清楚如何使用CONNECT BY子句来做到这一点。任何人都可以在这方面帮助?
SELECT term_name
FROM term
WHERE term_id IN
(SELECT term_id
FROM term_relationship
START WITH related_term_id = 123
CONNECT BY NOCYCLE PRIOR term_id = related_term_id)
AND term_id IN
(SELECT term_id
FROM term_relationship
START WITH related_term_id = 456
CONNECT BY NOCYCLE PRIOR term_id = related_term_id)
相反,只有不同的初始值做同样的CONNECT BY
查询两次的你怎么样通过提供做一次都开始值的子查询的一个实例。这一变化将让你的所有相关或者您的初始值的term_id
s,但是,你想只有那些涉及到这两个起始值term_id
s。为了得到这一点,你则需要组的结果通过term_id并限制具有多于一个的计数这些结果:
SELECT term_name
FROM term
WHERE term_id IN
(SELECT term_id
FROM term_relationship
START WITH related_term_id in (123, 456)
CONNECT BY NOCYCLE PRIOR term_id = related_term_id
group by term_id having count(*) >= 2)
编辑 与上面的代码我对你们数据的假设可能不正确。我以为树状结构,你用节点上的一个分支开始在图表A中向根向上行进等,然而,如果你的数据看起来像图B,那么上面的查询将如果你开始在节点7,9失败作为节点7具有两个路径回节点1,和上面的查询将返回节点1的两倍,从而正确地识别它作为一个公共节点。
A) -(1)- B) -(1)-
/ | \ (8) / | \ (8)
(2) | (3) | (2) | (3) |
| (4) | (9) | (4) | (9)
(5) (6) (5) (6)
| \ /
(7) -(7)-
下面的查询校正这一点,将正确地识别为起始然而节点7和9没有节点是共同的,与起始节点7和节点4 1被识别为公共节点:
SELECT term_name
FROM term
WHERE term_id IN
(SELECT term_id
FROM term_relationship
START WITH related_term_id in (123, 456)
CONNECT BY NOCYCLE PRIOR term_id = related_term_id
group by term_id
having count(distinct connect_by_root related_term_id) >= 2)