Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Wyjście MYSQL w formacie drzewa LUB Poziom dodawania (Parent-Child)

Chociaż nie możesz zrobić z pojedynczym zapytaniem, możesz to zrobić za pomocą procedury składowanej... Jedynym wymaganiem wstępnym jest dodanie 2 kolejnych rekordów do istniejącej tabeli przykładowej, aby reprezentować, że „C1” i „C2” SĄ najwyższy poziom... Dodaj rekord, w którym pole „Nadrzędny” jest puste, a poziom podrzędny to „C1” i drugi dla „C2”. To „przygotuje” najwyższy poziom rodzicielski. dla kolejnego skojarzenia hierarchii, w przeciwnym razie nie masz początkowej „podstawy” hierarchii najwyższego poziomu. Wymaga również kolumny „klucza podstawowego” (którą utworzyłem w tym skrypcie jako „IDMyTable”, która jest sekwencyjna tylko 1-x, ale zakładam, że zamiast tego masz w tabeli kolumnę autoinkrementacji).

Dołączyłem wszystkie kolumny wyjściowe, aby pokazać, JAK jest zbudowany, ale założeniem tej procedury jest utworzenie tabeli na podstawie oczekiwanych danych wyjściowych kolumny, ale dodatkowo, aby utrzymać hierarchiczną reprezentację w trakcie jej tworzenia. Aby UPEWNIĆ SIĘ, że zachowują prawidłową orientację, gdy warstwy stają się głębsze, łączę kolumnę „ID” — zobaczysz, jak to działa w końcowym zestawie wyników.

Następnie, w końcowym zestawie wyników, wstępnie dopełniam spacje w oparciu o to, jak głębokie są dane hierarchii.

Pętla doda wszelkie rekordy na podstawie ich rodzica znajdującego się w poprzednim zestawie wyników, ale tylko wtedy, gdy identyfikator nie został jeszcze dodany (zapobiega duplikatom)...

Aby zobaczyć, jak cykliczne zamówienie było stale dodawane, możesz uruchomić ostatnie zapytanie BEZ zamówienia i zobaczyć, jak każda iteracja zakwalifikowała się i dodała poprzedni poziom hierarchii...

-- --------------------------------------------------------------------------------
-- 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. Dodaj nową kolumnę do wyników i połącz tabelę

  2. Odmowa dostępu dla użytkownika „[chroniony adres e-mail]” (przy użyciu hasła:NIE)

  3. Zwracanie zestawu wyników

  4. INNER JOIN ten sam stół

  5. Pokaż hosta MySQL za pomocą polecenia SQL