Выбор всех строк-потомков из таблицы Oracle, представляющей древовидную структуру - PullRequest
3 голосов
/ 17 января 2011

У меня есть таблица MYTYPE в Oracle 10g, представляющая древовидную структуру, которая выглядит примерно так:

ID | PARENTID | DETAIL

Я хотел бы выбрать все строки в MYTYPE, которые являются потомками определенного идентификатора, чтобы я мог создавать запросы в других местах, например:

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

Каков экономически эффективный способ построения набора потомков, желательно без использования PL / SQL?

Ответы [ 4 ]

8 голосов
/ 17 января 2011

Oracle не поддерживал иерархический синтаксис ANSI с использованием рекурсивного факторинга подзапросов (CTE в синтаксисе SQL Server) до 11g R2, поэтому необходимо использовать собственный синтаксис Oracle CONNECT BY (поддерживается начиная с v2):

   SELECT t.*
      FROM MYTABLE t
START WITH t.parentid = ?
CONNECT BY PRIOR t.id = t.parentid

Замените знак вопроса на родительский элемент, для которого вы хотите найти иерархические данные.

Справка:

2 голосов
/ 18 января 2011

Управление иерархическими данными с использованием столбцов ID,ParentID в СУБД известно как модель Список смежностей . В то время как очень легко реализовать и поддерживать (то есть вставить, обновить, удалить), определить родословную (то есть предков и потомков) дорого. Как уже написали другие ответы, Oracle CONNECT BY будет работать, но это дорогостоящая операция. Возможно, вам лучше представлять свои данные по-другому.

Для вашего случая самое простое решение - добавить в вашу схему таблицу, называемую Hierarchy Bridge , и добавить столбец LEVEL в исходную таблицу. В таблице есть столбцы ID,DescendantID, в результате чего выбор по ID дает все записи потомков, а выбор по DescentantID - все записи предков. LEVEL необходимо в базовой таблице для заказа записей. Таким образом, вы делаете компромисс между дорогими обновлениями и дешевым чтением, что и подразумевает ваш вопрос.

Другие возможности, которые включают изменение ваших базовых данных, включают представления «Вложенный набор» и «Материализованный путь». Это предлагает аналогичные компромиссы более дорогих записей для гораздо более дешевых операций чтения. Полный список опций, плюсов и минусов, а также некоторые замечания по реализации см. В моем предыдущем вопросе по теме .

1 голос
/ 01 февраля 2013

Вот подробные сведения о функциях «Connect by» в Oracle.http://psoug.org/reference/connectby.html

1 голос
/ 17 января 2011

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

...