How to do MySQL Looped Join which tests if results are complete?

后端 未结 2 888
渐次进展
渐次进展 2021-01-17 01:59

Situation:
I have a mysql table of directories. Each directory has a parent directory (stored as parentID), up to the point where the root directory has a parentID of

相关标签:
2条回答
  • 2021-01-17 02:50

    Well, It could be you did not find a good web example, because you did use the wrong search-term. The problem described fits perfectly into oracles CONNECT BY PRIOR statement and by googling for mysql-equivalents to this statement you find http://explainextended.com/2009/03/17/hierarchical-queries-in-mysql/ quite fast.

    Because its not that easy (and I dont have a mysql-db to rape here) to write this stuff, just have a glance at the good examples given (you can even do that without deployed functions via http://explainextended.com/2009/07/20/hierarchical-data-in-mysql-parents-and-children-in-one-query/.

    If you still dont get the hang of those, I might be able to help at home.

    0 讨论(0)
  • 2021-01-17 02:54

    Alright, found the time to actually deploy a simple database with a similar structure as described.

    The table is the following:

    CREATE TABLE `t_hierarchy` (
        `rowID` INT(11) NULL DEFAULT NULL,
        `name` VARCHAR(50) NULL DEFAULT NULL COLLATE 'latin1_general_ci',
        `parentID` INT(11) NULL DEFAULT NULL
    );
    

    I basicly inserted the exact same stuff as you have given above but used NULL values instead of 0 for root/no parent

    What I've done is the quite cryptic example from http://explainextended.com/2009/07/20/hierarchical-data-in-mysql-parents-and-children-in-one-query/ . and just corrected the column names to fit mine.

    Since this only generates you a recursive hierarchy, I just added a stupid join into the example ( ad.rowID = qi.id ):

     SELECT  qi.id, qi.parent, ad.rowId, ad.name, level
    FROM    (
            SELECT  @r AS id,
                    (
                    SELECT  @r := parentID
                    FROM    t_hierarchy
                    WHERE   rowID = id
                    ) AS parent,
                    @l := @l + 1 AS level
            FROM    (
                    SELECT  @r := 5, -- change this 5 to the directory ID you want to resolve
                            @l := 0,
                            @cl := 0
                    ) vars,
                    t_hierarchy h
            WHERE   @r <> 0
            ORDER BY
                    level DESC
            ) qi, t_hierarchy ad
            WHERE ad.rowID = qi.id
    

    And this generates the follwoing (desired) output:

    id parent rowId name level

    1 NULL 1 Dir1 3

    3 1 3 Subdir1 2

    5 3 5 Subdir3 1

    Level is a helper column which tells you how "deep" it had to resolve to reach this. All you will have to do is change the "5" next to @r := to the directory ID from where you wanna iterate down.

    If you want to switch the direction (from up to down) simply sort by level column ([...] WHERE ad.rowID = qi.id ORDER BY level ASC )

    Hope this helps you out.

    Edit: qi.id and ad.rowID are duplicates, just remove one of them ;-)... damn I hate that hierarchy stuff

    0 讨论(0)
提交回复
热议问题