我在 Oracle 10g 中有一个代表树结构的表 MYTYPE,它是这样的:
ID | PARENTID | DETAIL
我想选择 MYTYPE 中作为特定 ID 后代的所有行,以便我可以在其他地方创建查询,例如:
SELECT *
FROM MYDETAIL
WHERE MYTYPEID IN [all MYTYPE which are descendants of some ID];
什么是构建后代集的经济高效的方法,最好不使用 PL/SQL?
我在 Oracle 10g 中有一个代表树结构的表 MYTYPE,它是这样的:
ID | PARENTID | DETAIL
我想选择 MYTYPE 中作为特定 ID 后代的所有行,以便我可以在其他地方创建查询,例如:
SELECT *
FROM MYDETAIL
WHERE MYTYPEID IN [all MYTYPE which are descendants of some ID];
什么是构建后代集的经济高效的方法,最好不使用 PL/SQL?
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
将问号替换为您要查找分层数据所依据的父级。
参考:
使用 RDBMS 中的列管理分层数据ID,ParentID
称为邻接列表模型。虽然很容易实现和维护(即插入、更新、删除),但确定血统(即祖先和后代)的成本很高。正如其他答案已经写的那样,甲骨文CONNECT BY
会起作用,但这是一项昂贵的操作。您最好以不同的方式表示您的数据。
对于您的情况,最简单的解决方案可能会向您的架构添加一个所谓的层次结构桥LEVEL
表,并向您的原始表添加一列。该表有列ID,DescendantID
,选择 ID 会给出所有后代记录,选择 DescentantID 会给出所有祖先记录。LEVEL
在基表上对记录进行排序是必需的。通过这种方式,您可以在昂贵的更新与便宜的读取之间进行权衡,这就是您的问题暗示您想要的。
涉及更改基础数据的其他可能性包括嵌套集和物化路径表示。这提供了类似的权衡,即更昂贵的写入与更便宜的读取。有关选项、优缺点和一些实施说明的完整列表,请参阅我之前关于该主题的问题。
Oracle 可以进行递归查询。尝试调查start with ... connect by
,如下所示:
Select *
from MYDETAIL
Starting with PARENTID= 1 --or whatever the root ID is
connect by PARENTID = prior ID
以下是 oracle 中“连接方式”功能的详细信息。 http://psoug.org/reference/connectby.html