Выберите из таблицы, которая использует материализованный путь для кодирования дерева, упорядоченного по глубине (без рекурсии / ltree) - PullRequest
6 голосов
/ 01 февраля 2012

У меня есть таблица в реляционной базе данных, в которой я кодирую дерево, используя технику, известную как Материализованный путь (также известный как столбец Lineage). То есть для каждого узла в моем дереве у меня есть строка в таблице, а для каждой строки у меня есть строковый столбец с именем ancestry, в котором я сохраняю путь от корневого узла до узла, представленного этой строкой.

Возможно ли, и если да - каким образом, выберите строки в таблице, упорядоченные по предзаказу , то есть они должны появиться в наборе результатов в том порядке, в котором будет отображаться дерево глубина первого . Я использую MySQL - поэтому без рекурсивных запросов и без расширения ltree .

Например, дерево, его таблица и выборка упорядочены по предзаказу:

 1        SELECT * FROM nodes   SELECT * FROM nodes ORDER BY ?depth_first_visit_order?
| \       id | ancestry         id | ancestry
2   3     -------------         -------------
|  | \    1  | NULL             1  | NULL           NOTE: I don't care about the
4  5  6   2  | 1                2  | 1                    order of siblings!
   |      3  | 1                4  | 1/2
   7      4  | 1/2              3  | 1
          5  | 1/3              5  | 1/3
          6  | 1/3              7  | 1/3/5
          7  | 1/3/5            6  | 1/3

Примечание. Я заинтересован в том, чтобы сделать это по материализованному пути кодирования!
По теме: Какие есть варианты хранения иерархических данных в реляционной базе данных?

Ответы [ 2 ]

1 голос
/ 14 февраля 2012

Я верю, что вы хотите, это алфавитный вид.

SELECT id, ancestry, ancestry + '/' + CAST(id as nvarchar(10)) AS PathEnumeration
FROM nodes
ORDER BY 3 ASC;

Я действительно не помню, как MySQL объединяется, но я уверен, что мой смысл ясен.

1
1/2
1/2/4
1/3
1/3/5
1/3/5/7
1/3/6

Обратите внимание, что это алфавитный вид, поэтому 11 будет отображаться до 2. Но вы сказали, что вас не заботит порядок братьев и сестер.Я бы, конечно, переписал его как вложенный набор;)

0 голосов
/ 01 февраля 2012

это будет порядок по последнему номеру вашей "родословной"

select *, 
Substring(ancestry,LEN(ancestry) - Charindex('/',Reverse(ancestry))+2, LEN(ancestry)) as END_CHAR
from nodes
order by END_CHAR desc

Я не пробовал с числами больше 9, возможно, вам придется привести к int

...