sql >> Databáze >  >> RDS >> Mysql

Výstup MYSQL ve stromovém formátu NEBO Přidání úrovně (rodič-dítě)

I když si nevystačíte s jedním dotazem, vystačíte si s uloženou procedurou... Jediným předběžným požadavkem je přidat 2 další záznamy do vaší stávající vzorové tabulky, aby reprezentovaly, že „C1“ a „C2“ JSOU nejvyšší úroveň... Přidejte záznam, kde je pole "Rodič" prázdné a podřízená úroveň je "C1" a další pro "C2". Tím se „připraví“ nejvyšší nadřazená úroveň. pro následné přidružení hierarchie, jinak nemáte žádný počáteční „základ“ hierarchie nejvyšší úrovně. Vyžaduje také sloupec "primární klíč" (který jsem v tomto skriptu vytvořil jako "IDMyTable", který je pouze 1x sekvenční, ale předpokládá se, že místo něj máte v tabulce sloupec s automatickým přírůstkem).

Zahrnul jsem všechny výstupní sloupce, abych ukázal, JAK je sestaven, ale předpokladem této rutiny je vytvořit tabulku založenou na očekávaných výstupech sloupců, ale navíc udržet hierarchickou reprezentaci po proudu při jejím vytváření. Abych se ujistil, že si zachovají správnou orientaci, jak se vrstvy prohlubují, zřetězuji sloupec „ID“ – uvidíte, jak to funguje v konečné sadě výsledků.

Poté v konečné sadě výsledků předvyplňuji mezery podle toho, jak hluboko jsou data hierarchie.

Smyčka přidá jakékoli záznamy na základě jejich nadřazeného nalezeného v předchozí sadě výsledků, ale pouze v případě, že ID již nebylo přidáno (zabrání duplicitám)...

Chcete-li vidět, jak byla cyklická objednávka neustále připojována, můžete spustit poslední dotaz BEZ objednávky a podívat se, jak byla použita každá kvalifikovaná a přidaná iterace předchozí úrovně hierarchie...

-- --------------------------------------------------------------------------------
-- 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. Jak zkontrolovat stav plánovače událostí mysql

  2. Oprava „CHYBA:  každý dotaz UNION musí mít stejný počet sloupců“ v PostgreSQL

  3. Jak povolit mezipaměť dotazů MySQL

  4. java.sql.SQLException:Před spuštěním sady výsledků