Mysql
 sql >> база данни >  >> RDS >> Mysql

MYSQL изход в дървовиден формат ИЛИ Добавяне на ниво (Родител-Дете)

Въпреки че не можете да направите с една заявка, можете да направите със съхранена процедура... Единственото предварително изискване, трябва да добавите още 2 записа към съществуващата си примерна таблица, за да представите, че "C1" и "C2" СА най-горното ниво... Добавете запис, където полето "Родител" е празно, а дъщерното ниво е "C1" и друго за "C2". Това ще "подготви" най-високото родителско ниво. за последваща йерархична асоциация, в противен случай нямате начална "база" на йерархията от най-високо ниво. Той също така изисква колона „първичен ключ“ (която създадох в този скрипт като „IDMyTable“, която е само 1-x последователна, но предполага, че имате колона с автоматично увеличение в таблицата, която да използвате вместо това).

Включих всички изходни колони, за да покажа КАК е изградена, но предпоставката на тази рутина е да се създаде таблица на базата на очакваните изходи на колони, но допълнително, за да задържи йерархичното представяне надолу по веригата, докато се изгражда. За да се уверя, че запазват правилната ориентация, докато слоевете се задълбочават, свързвам колоната „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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Entity Framework MySQL tinyint(1) System.Boolean.Parse FormatException

  2. Показване на всички таблици. Функционалност, подобна на описанието

  3. Как да „дехексирате“ число в MySQL

  4. Как да проверя дали PHP вече е свързан към база данни?

  5. CakePHP Връзката с базата данни Mysql липсва или не може да бъде създадена