MySQL hierarchical recursive query [требует правки]

436
13 января 2017, 08:54

У меня есть таблица

мне надо давать staff_id и взять все ее parent_staff, прошу помоч,заранее спасибо

Answer 1

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

Циклов в SQL не бывает, так что будем его эмулировать с помощью произвольной таблицы (или запроса) который выдаст количество строк, достаточное для получения всех родителей. В данном примере я решил в качестве такого курсора использовать уникальные parent_staff из таблицы, так как их заведомо не меньше, чем нужно итераций "цикла". Если известна максимально возможная глубина иерархии лучше (для быстродействия) ограничить его limit.

select distinct id
  from (
    select @id:=(select parent_staff from staff where staff_id=@id) id
      from (select distinct parent_staff from staff) as curs,
           (select @id:=2 /* стартовый staff_id */ ) A
) B
Answer 2
with recursive tree (TABLE, staff_id, level, pathstr)
as (select TABLE, staff_id, 0, cast('' as text) 
   from tree_sample
   where staff_parent_staff is null 
union all
   select tree_sample.TABLE, tree_sample.staff_id, t.level + 1, tree.pathstr + tree_sample.TABLE
   from tree_sample 
     inner join tree on tree.staff_id = tree_sample.staff_parent_staff) 
select staff_id, space( level ) + TABLE as TABLE 
from tree 
order by pathstr
Answer 3

Рекурсивных запросов в stable у MySQL пока нет, так что только ХП.

С другой стороны, рекурсия тут не нужна, от слова "совсем". Схематичненько ежели, то будет где-то так:

CREATE PROCEDURE get_all_parents(IN child_id BIGINT)
BEGIN
    DECLARE cnt BIGINT DEFAULT 0;
    DROP TEMPORARY TABLE IF EXISTS tmp_parents;
    CREATE TEMPORARY TABLE tmp_parents(id BIGINT UNIQUE) ENGINE=Memory;
    INSERT INTO tmp_parents(id) SELECT child_id;
    WHILE (SELECT COUNT(*) FROM tmp_parents) > cnt
        SELECT COUNT(*) INTO cnt FROM tmp_parents;
        INSERT IGNORE INTO tmp_parents(id)
            SELECT parent_id 
            FROM datatable 
            WHERE id IN (
                        SELECT id FROM tmp_parents
                        );
    END WHILE;
    /* DELETE FROM tmp_parents WHERE id = child_id; */
    SELECT id FROM tmp_parents;
    DROP TEMPORARY TABLE tmp_parents;
END;
READ ALSO
Как скачать базу даных Википедии?

Как скачать базу даных Википедии?

Как скачать базу даных Википедии (английской) для того, чтобы в SQL Management Studio можно было с базой даных работать?

315
Категория зависит от страны OpenCart?

Категория зависит от страны OpenCart?

Здравствуйте, мне нужно сделать чтоб категории открывались при выборе страны (как на скриншоте)

379
Почему RecyclerView null?

Почему RecyclerView null?

Код фрагмента:

497
Как отобразить команду “tasklist” window в окне JavaFX [требует правки]

Как отобразить команду “tasklist” window в окне JavaFX [требует правки]

Нужно написать программу которая сможет отобразить все данные которые выводит команда tasklist в окно JavaFX и потом иметь возможность сохранить...

315