sql >> Database >  >> RDS >> Mysql

MYSQL-uitvoer in boomstructuur OF Niveau toevoegen (Ouder-kind)

Hoewel u niet kunt doen met een enkele query, kunt u dat doen met een opgeslagen procedure... De enige vereiste is dat u nog 2 records aan uw bestaande voorbeeldtabel moet toevoegen om aan te geven dat "C1" en "C2" ZIJN het hoogste niveau... Voeg een record toe waarbij het veld "Ouder" leeg is en het onderliggende niveau "C1" is en een ander voor "C2". Dit zal het bovenste bovenliggende niveau "voorbereiden". voor daaropvolgende hiërarchiekoppeling, anders hebt u geen start "basis" van de hiërarchie op het hoogste niveau. Het vereist ook een kolom "primaire sleutel" (die ik in dit script heb gemaakt als "IDMyTable" die slechts 1-x opeenvolgend is, maar zou aannemen dat u in plaats daarvan een kolom voor automatisch ophogen in uw tabel hebt).

Ik heb alle uitvoerkolommen toegevoegd om te laten zien HOE het is gebouwd, maar het uitgangspunt van deze routine is om een ​​tabel te maken op basis van de verwachte kolomuitvoer, maar extra om de hiërarchische weergave stroomafwaarts vast te houden terwijl deze wordt gebouwd. Om er zeker van te zijn dat ze de juiste oriëntatie behouden naarmate de lagen dieper worden, voeg ik de kolom 'ID' samen -- je zult zien hoe het werkt in de uiteindelijke resultatenset.

Vervolgens vul ik in de uiteindelijke resultatenset vooraf spaties op basis van hoe diep de hiërarchiegegevens ook zijn.

De lus voegt alle records toe op basis van hun bovenliggende gevonden in de voorgaande resultatenset, maar alleen als de ID nog niet is toegevoegd (voorkom duplicaten)...

Om te zien hoe de cyclische volgorde constant werd toegevoegd, kunt u de laatste query uitvoeren ZONDER de volgorde door en zien hoe elke iteratie gekwalificeerd en toegevoegd is aan het vorige hiërarchieniveau...

-- --------------------------------------------------------------------------------
-- 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. Hoe kan ik een batch invoegen in een Oracle-database met Python?

  2. MySQL Verwijder dubbele rijen met dezelfde kolomwaarde

  3. MySQL:snelste manier om het aantal rijen te tellen

  4. Upgrades zonder downtime gemakkelijk gemaakt met ClusterControl