Получение данных иерархии из самоссылки на таблицы

Скажем, у Вас есть следующая таблица:

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}
{"item_id":3, "глубина":1}
{"item_id":4, "глубина":1}
{"item_id":5, "глубина":2}

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

22
задан Reinstate Monica 17 September 2014 в 22:42
поделиться

5 ответов

Для них необходимо написать собственные классы, повторно выполнив все необходимые операторы.

-121--2478542-

Ахх, товарищ Ада путешественник я вижу.

Единственный реальный способ сделать это в C++ - объявить классы. Что-то вроде:

class first_100 {
public:
    explicit first_100(int source) {
        if (source < 1 || source > 100) {
           throw range_error;
        }
        value = source;
    };
    // (redefine *all* the int operators here)
private:
    int value;
};

Необходимо определить конструктор int явным образом , чтобы C++ не использовал его для неявного преобразования между типами. Это путь, что это не сработает:

first_100 centum = first_100(55);
int i = centum;

, но что-то подобное может (если вы его определите):

int i = centum.to_int();
-121--2478544-

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

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

 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

Из этого можно форматировать по желанию.

23
ответ дан 29 November 2019 в 05:10
поделиться

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

Особенно Вас должна заинтересовать часть о "Модели вложенных множеств" и "Поиск глубины узлов".

5
ответ дан 29 November 2019 в 05:10
поделиться

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 и выбирает всех дочерних узлов этих узлов вместе с их глубиной в дереве.

3
ответ дан 29 November 2019 в 05:10
поделиться
2
ответ дан 29 November 2019 в 05:10
поделиться

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

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

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

0
ответ дан 29 November 2019 в 05:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: