Flatten Adjacency List Hierarchy To A List Of All Paths

前端 未结 4 1345
梦如初夏
梦如初夏 2020-12-13 01:14

I have a Table that stores Hierarchical information using the Adjacency List model. (uses a self referential key - example below. This Table may look familiar):

<         


        
4条回答
  •  情深已故
    2020-12-13 01:51

    To do multi-level queries across a simple adjacency-list invariably involves self-left-joins. It's easy to make a right-aligned table:

    SELECT category.category_id,
        ancestor4.category_id AS lvl4,
        ancestor3.category_id AS lvl3,
        ancestor2.category_id AS lvl2,
        ancestor1.category_id AS lvl1
    FROM categories AS category
        LEFT JOIN categories AS ancestor1 ON ancestor1.category_id=category.category_id
        LEFT JOIN categories AS ancestor2 ON ancestor2.category_id=ancestor1.parent
        LEFT JOIN categories AS ancestor3 ON ancestor3.category_id=ancestor2.parent
        LEFT JOIN categories AS ancestor4 ON ancestor4.category_id=ancestor3.parent;
    

    To left-align it like your example is a bit more tricky. This comes to mind:

    SELECT category.category_id,
        ancestor1.category_id AS lvl1,
        ancestor2.category_id AS lvl2,
        ancestor3.category_id AS lvl3,
        ancestor4.category_id AS lvl4
    FROM categories AS category
        LEFT JOIN categories AS ancestor1 ON ancestor1.parent IS NULL
        LEFT JOIN categories AS ancestor2 ON ancestor1.category_id<>category.category_id AND ancestor2.parent=ancestor1.category_id
        LEFT JOIN categories AS ancestor3 ON ancestor2.category_id<>category.category_id AND ancestor3.parent=ancestor2.category_id
        LEFT JOIN categories AS ancestor4 ON ancestor3.category_id<>category.category_id AND ancestor4.parent=ancestor3.category_id
    WHERE
        ancestor1.category_id=category.category_id OR
        ancestor2.category_id=category.category_id OR
        ancestor3.category_id=category.category_id OR
        ancestor4.category_id=category.category_id;
    

    would work for n-tier hierarchies.

    Sorry, arbitrary-depth queries are not possible in the adjacency-list model. If you are doing this kind of query a lot, you should change your schema to one of the other models of storing hierarchical information: full adjacency relation (storing all ancestor-descendent relationships), materialised path, or nested sets.

    If the categories don't move around a lot (which is usually the case for a store like your example), I would tend towards nested sets.

提交回复
热议问题