4

我在 Oracle 10g 中有一个代表树结构的表 MYTYPE,它是这样的:

ID | PARENTID | DETAIL

我想选择 MYTYPE 中作为特定 ID 后代的所有行,以便我可以在其他地方创建查询,例如:

SELECT * 
  FROM MYDETAIL 
 WHERE MYTYPEID IN [all MYTYPE which are descendants of some ID];

什么是构建后代集的经济高效的方法,最好不使用 PL/SQL?

4

4 回答 4

9

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

将问号替换为您要查找分层数据所依据的父级。

参考:

于 2011-01-17T20:20:58.313 回答
2

使用 RDBMS 中的列管理分层数据ID,ParentID称为邻接列表模型。虽然很容易实现和维护(即插入、更新、删除),但确定血统(即祖先和后代)的成本很高。正如其他答案已经写的那样,甲骨文CONNECT BY会起作用,但这是一项昂贵的操作。您最好以不同的方式表示您的数据。

对于您的情况,最简单的解决方案可能会向您的架构添加一个所谓的层次结构桥LEVEL表,并向您的原始表添加一列。该表有列ID,DescendantID,选择 ID 会给出所有后代记录,选择 DescentantID 会给出所有祖先记录。LEVEL在基表上对记录进行排序是必需的。通过这种方式,您可以在昂贵的更新与便宜的读取之间进行权衡,这就是您的问题暗示您想要的。

涉及更改基础数据的其他可能性包括嵌套集和物化路径表示。这提供了类似的权衡,即更昂贵的写入与更便宜的读取。有关选项、优缺点和一些实施说明的完整列表,请参阅我之前关于该主题的问题

于 2011-01-18T11:27:49.700 回答
1

Oracle 可以进行递归查询。尝试调查start with ... connect by,如下所示:

Select *
from MYDETAIL
Starting with PARENTID= 1 --or whatever the root ID is
connect by PARENTID = prior ID

http://psoug.org/reference/connectby.html

于 2011-01-17T20:21:17.050 回答
1

以下是 oracle 中“连接方式”功能的详细信息。 http://psoug.org/reference/connectby.html

于 2013-02-01T06:12:09.323 回答