Получение данных иерархии из самообращающихся таблиц - PullRequest
22 голосов
/ 04 февраля 2010

Допустим, у вас есть следующая таблица:

items(item_id, item_parent)  

... и это таблица с самоссылкой - item_parent относится к item_id.

Какой SQL-запрос вы бы использовали, чтобы ВЫБРАТЬ все элементы в таблице вместе с их глубиной, где глубина элемента - это сумма всех родителей и дедов этого элемента.

Если содержание таблицы следующее:

item_id     item_parent
----------- -----------
1           0          
2           0            
3           2          
4           2          
5           3          

... запрос должен получить следующий набор объектов:

{ "item_id": 1, "глубина": 0}
{ "Item_id": 2, "глубина": 0} * * 1016 { "Item_id": 3, "глубина": 1}
{ "Item_id": 4, "глубина": 1}
{"item_id": 5, "глубина": 2}

P.S. Я ищу подход, поддерживаемый MySQL.

Ответы [ 5 ]

23 голосов
/ 04 февраля 2010

Если база данных SQL 2005/2008, то ...

Самый простой способ получить это - использовать CTE (Common Table Expression), предназначенный для рекурсии.

 WITH myCTE (Item_id, Depth)
 AS
 (
    Select Item_ID, 0 as Depth From yourTable where Item_Parent=0
    Union ALL
    Select yourTable.Item_ID, Depth + 1 
    From yourTable 
    inner join myCte on yourTable.item_Parent = myCte.Item_Id
 )

 Select Item_id, Depth from myCTE

Вывод выглядит следующим образом:

Item_Id  Depth
    1   0
    2   0
    3   1
    4   1
    5   2

От этого вы можете отформатировать его, как вы хотите.

4 голосов
/ 04 февраля 2010

На веб-сайте mysql есть хорошая техническая статья об иерархических данных в MySql: Управление иерархическими данными в MySQL - вы можете найти там несколько подробных решений с за и против.Особенно вас могут заинтересовать разделы «Модель вложенного множества» и «Поиск глубины узлов».

3 голосов
/ 04 февраля 2010

Oracle имеет очень удобный синтаксис для получения иерархических данных, таких как:

select
    item_id,
    item_parent,
    level as depth
from
    items
connect by
    prior item_id = item_parent
start with
    item_parent not in (select item_id from items)

Это начинается с корневых узлов ваших деревьев как тех элементов, у которых item_parent не существует в таблице как item_id, и выбирает всех потомков этих узлов вместе с их глубиной в дереве.

2 голосов
/ 04 февраля 2010
0 голосов
/ 18 марта 2010

Мне нужно найти решение для той же задачи, нашел несколько статей, но все еще не выбрал путь ...

http://explainextended.com/2009/07/20/hierarchical-data-in-mysql-parents-and-children-in-one-query/

Возможно, эти ссылки могут вам помочь. Если вы найдете хорошее решение - пожалуйста, опубликуйте его здесь. Мне не разрешено публиковать более одной ссылки - я добавлю некоторые к следующим сообщениям

...