Вопрос по sql, mysql – Вывод MYSQL в древовидном формате ИЛИ Добавление уровня (Parent-Child)

3

Ниже то, что у меня в таблице.

myTable
++++++++++++++++++++
Parent   +  Child
++++++++++++++++++++
  C1     +    G1
  C1     +    G2
  C1     +    G3
  G3     +    D1
  G3     +    D2
  C1     +    G4
  G4     +    D3
  G4     +    D4
  C2     +    G5
  C2     +    G6
  C2     +    G7
  C2     +    G8
 ++++++++++++++++++++

Что я хочу, как показано ниже, используя MYSQL.

C1
  G1
  G2
  G3
    D1
    D2
  G4
    D3
    D4

C2
  G5
  G6
  G7
  G8

Пожалуйста, дайте мне знать, если это возможно в MYSQL. На выходе что-то вродеTREE.

Update 1

If I get new table like below is also fine so that I can use этот пример.

++++++++++++++++++++++++++++++++++++++++
Parent   +  Child   + PLevel  + CLevel
++++++++++++++++++++++++++++++++++++++++
  C1     +    G1    +   1    +   2
  C1     +    G2    +   1    +   2
  C1     +    G3    +   1    +   2
  G3     +    D1    +   2    +   3
  G3     +    D2    +   2    +   3
  C1     +    G4    +   1    +   2
  G4     +    D3    +   2    +   3
  G4     +    D4    +   2    +   3
  C2     +    G5    +   1    +   2
  C2     +    G6    +   1    +   2
  C2     +    G7    +   1    +   2
  C2     +    G8    +   1    +   2
++++++++++++++++++++++++++++++++++++++++

NOTE : Я начал уровень с 1 (в примере у меня уровень начинается с 0). Если я получу эту новую таблицу с уровнем, начинающимся с 0, тоже подойдет.

Как уже говорили другие, MySQL не поддерживает рекурсивные функции, поэтому он не очень подходит для этой модели списка смежности для хранения иерархических данных. Возможно, вы захотите рассмотреть возможность реструктуризации ваших данных для использования либо вложенных наборов, либо таблиц закрытия. Увидетьthis answer для дополнительной информации. eggyal
Это может помочь вамexplainextended.com/2009/03/17/hierarchical-queries-in-mysql Gowri

Ваш Ответ

4   ответа
0

вероятно, придется использовать клиентскую рекурсию.

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

Error: User Rate Limit ExceededareError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededwhileError: User Rate Limit Exceeded
Error: User Rate Limit ExceededbuildError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Fahim Parkar
0

вы могли бы использовать что-то вроде:

  SELECT Child,CONCAT(LPAD('',Clevel,' '),Child),etc from tablename

Реструктуризация заключается в том, что вам понадобится корневой узел в виде строки с родительским узлом 0. Вы можете добавить свой собственный порядок на уровне parent / child / C, чтобы получить последовательность по желанию.

Я знаю, что это сделано несколько лет назад, но это может спасти кого-то еще от некоторых усилий!

0

function fn_CalcLevel(int @ID) 
As Begin
  Declare @ParentID int
  Select @ParentID = ParentID From Table1 where ID = @ID

  IF (@ParentID IS NULL) Return 1 Else Return 1+fn_CalcLevel(@ParentID)
End

затем создайте свой запрос, например ниже

Select *, fn_CalcLevel(Table1.ID) as Level
From Table1
0

вы можете сделать это с помощью хранимой процедуры ... Единственное предварительное требование: вам нужно добавить еще 2 записи в вашу существующую примерную таблицу, чтобы представить это "C1"; и "C2"; ARE верхнего уровня ... Добавить запись, где & quot; Parent & quot; поле не заполнено, а дочерний уровень равен «C1»; и другой для "C2". Это "подготовит" самый верхний родительский уровень. для последующего связывания иерархии, в противном случае у вас нет начальной «основы» иерархии верхнего уровня. Также требуется «первичный ключ»; столбец (который я "создал в этом сценарии как" IDMyTable ", который является всего лишь 1-кратным последовательным, но предполагает, что у вас есть столбец с автоинкрементом в таблице для использования вместо него).

Я включил все выходные столбцы, чтобы показать, КАК он построен, но предпосылка этой подпрограммы состоит в том, чтобы создать таблицу на основе ожидаемых выходных данных столбца, но при этом дополнительно удерживать иерархическое представление в нисходящем направлении по мере его построения. Чтобы убедиться, что они сохраняют правильную ориентацию по мере того, как слои становятся глубже, я конкатенирую «ID». столбец - вы увидите, как это работает в окончательном наборе результатов.

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

Цикл добавит любые записи, основываясь на том, что их родительский элемент был найден в предыдущем наборе результатов, но только если идентификатор еще не был добавлен (предотвратить дублирование) ...

Чтобы увидеть, как циклический порядок постоянно добавлялся, вы можете выполнить последний запрос БЕЗ заказа и посмотреть, как каждая итерация соответствовала и добавляла предыдущий уровень иерархии ...

-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$

CREATE DEFINER=`root`@`localhost` PROCEDURE `GetHierarchy2`()
BEGIN
    -- prepare a hierarchy level variable 
    set @hierlvl := 00000;

    -- prepare a variable for total rows so we know when no more rows found
    set @lastRowCount := 0;

    -- pre-drop temp table
    drop table if exists MyHierarchy;

    -- now, create it as the first level you want... 
    -- ie: a specific top level of all "no parent" entries
    -- or parameterize the function and ask for a specific "ID".
    -- add extra column as flag for next set of ID's to load into this.
    create table MyHierarchy as
    select 
            t1.IDMyTable,
            t1.Child AS Parent,
            @hierlvl as IDHierLevel,
            cast( t1.IDMyTable as char(100)) FullHierarchy
        from
            MyTable t1
        where
                t1.Parent is null
            OR t1.Parent = '';


    -- how many rows are we starting with at this tier level
    set @lastRowCount := ROW_COUNT();

    -- we need to have a "primary key", otherwise our UPDATE
    -- statement will nag about an unsafe update command
    alter table MyHierarchy add primary key (IDMyTable);


    -- NOW, keep cycling through until we get no more records
    while @lastRowCount > 0 do

        -- NOW, load in all entries found from full-set NOT already processed
        insert into MyHierarchy
            select 
                    t1.IDMyTable,
                    t1.Child as Parent,
                    h1.IDHierLevel +1 as IDHierLevel,
                    concat_ws( ',', h1.FullHierarchy, t1.IDMyTable ) as FullHierarchy
                from
                    MyTable t1
                        join MyHierarchy h1
                            on t1.Parent = h1.Parent
                    left join
                        MyHierarchy h2
                            on t1.IDMyTable = h2.IDMyTable
                where
                    h2.IDMyTable is null;


        set @lastRowCount := row_count();

        -- now, update the hierarchy level
        set @hierLevel := @hierLevel +1;

    end while;


    -- return the final set now
    select 
            *, concat( lpad( ' ', 1 + (IDHierLevel * 3 ), ' ' ), Parent ) as ShowHierarchy
        from MyHierarchy
        order by FullHierarchy;

END

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