我在Oracle 10g中有一个表MYTYPE表示树结构,如下所示:
ID | PARENTID | DETAIL
我想选择MYTYPE中作为特定ID后代的所有行,这样我就可以在其他地方创建查询,例如:
SELECT *
FROM MYDETAIL
WHERE MYTYPEID IN [all MYTYPE which are descendants of some ID];
建立后代集的成本效益方法是什么,最好不使用PL / SQL?
答案 0 :(得分:8)
Oracle不支持在11g R2之前使用递归子查询因子(SQL Server语法中的CTE)的ANSI分层语法,因此您必须使用Oracle的本机CONNECT BY语法(从v2开始支持):
SELECT t.*
FROM MYTABLE t
START WITH t.parentid = ?
CONNECT BY PRIOR t.id = t.parentid
将问号替换为您想要查找基于的分层数据的父级。
参考:
答案 1 :(得分:2)
使用RDBMS中的ID,ParentID
列管理分层数据称为Adjacency List模型。虽然非常容易实现和维护(即插入,更新,删除),但确定谱系(即祖先和后代)的成本很高。正如其他答案已经写好的那样,Oracle的CONNECT BY
会起作用,但这是一项昂贵的操作。您可能最好以不同方式表示数据。
对于您的情况,最简单的解决方案可能是在您的架构中添加所谓的Hierarchy Bridge表,并在原始表中添加LEVEL
列。该表具有列ID,DescendantID
,其中选择ID给出所有后代记录,并且通过DescentantID选择给出所有祖先记录。基表上需要LEVEL
来订购记录。通过这种方式,您可以权衡廉价读取的昂贵更新,这正是您的问题所暗示的。
涉及更改基础数据的其他可能性包括嵌套集和物化路径表示。对于更便宜的读取,这提供了更昂贵的写入的类似权衡。有关选项的完整列表,优缺点以及一些实施说明see my previous question on the topic。
答案 2 :(得分:1)
Oracle可以执行递归查询。
尝试查看start with ... connect by
,如下所示:
Select *
from MYDETAIL
Starting with PARENTID= 1 --or whatever the root ID is
connect by PARENTID = prior ID
答案 3 :(得分:1)
以下是oracle中“connect by”功能的详细信息。 http://psoug.org/reference/connectby.html