Question

I'm learning about nested sets and their use in producing hierarchical lists. Among other resources, I'm specifically referring to http://www.artfulsoftware.com/mysqlbook/sampler/mysqled1ch20.html and http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/. Could someone please tell me what I'm doing wrong, as the depth for the items is incorrect when I query the data?

Here's a graphic representation of my example:

[Oh, no it's not! I'll try to edit it in for future users, once my rep level allows.]

I created a table in MySQL and inserted the data as follows:

CREATE TABLE page_temp (
    page_id INTEGER unsigned NOT NULL AUTO_INCREMENT,
    page_name VARCHAR(255) NOT NULL,
    lft INT NOT NULL,
    rgt INT NOT NULL,
    PRIMARY KEY (page_id)
);

INSERT INTO page_temp VALUES
    (28, 'g', 52, 53), 
    (27, 'f', 50, 51), 
    (26, 'e', 40, 41), 
    (25, 'd', 38, 39), 
    (24, 'c', 10, 11), 
    (23, 'b', 8, 9), 
    (22, 'a', 6, 7), 
    (21, 10, 49, 54), 
    (20, 9, 47, 48), 
    (19, 8, 43, 44), 
    (18, 7, 37, 42), 
    (17, 6, 29, 30), 
    (16, 5, 21, 22), 
    (15, 4, 19, 20), 
    (14, 3, 17, 18), 
    (13, 2, 5, 12), 
    (12, 1, 3, 4), 
    (11, 'H', 46, 55), 
    (10, 'G', 36, 45), 
    (9, 'F', 32, 33), 
    (8, 'E', 28, 31), 
    (7, 'D', 26, 27), 
    (6, 'C', 16, 23), 
    (5, 'B', 14, 45), 
    (4, 'A', 2, 13), 
    (3, 'III', 35, 56), 
    (2, 'II', 25, 34), 
    (1, 'I', 1, 24)
;

I then pull the set with this query:

SELECT CAST(node.page_name AS BINARY) AS title, node.lft, node.rgt, (COUNT(parent.page_name) - 1) AS depth 
    -> FROM page_temp AS node CROSS JOIN page_temp AS parent
    -> WHERE node.lft BETWEEN parent.lft AND parent.rgt
    -> GROUP BY title
    -> ORDER BY node.lft;
+-------+-----+-----+-------+
| title | lft | rgt | depth |
+-------+-----+-----+-------+
| I     |   1 |  24 |     0 |
| A     |   2 |  13 |     1 |
| 1     |   3 |   4 |     2 |
| 2     |   5 |  12 |     2 |
| a     |   6 |   7 |     3 |
| b     |   8 |   9 |     3 |
| c     |  10 |  11 |     3 |
| B     |  14 |  45 |     1 |
| C     |  16 |  23 |     2 |
| 3     |  17 |  18 |     3 |
| 4     |  19 |  20 |     3 |
| 5     |  21 |  22 |     3 |
| II    |  25 |  34 |     1 |
| D     |  26 |  27 |     2 |
| E     |  28 |  31 |     2 |
| 6     |  29 |  30 |     3 |
| F     |  32 |  33 |     2 |
| III   |  35 |  56 |     1 |
| G     |  36 |  45 |     2 |
| 7     |  37 |  42 |     3 |
| d     |  38 |  39 |     4 |
| e     |  40 |  41 |     4 |
| 8     |  43 |  44 |     3 |
| H     |  46 |  55 |     1 |
| 9     |  47 |  48 |     2 |
| 10    |  49 |  54 |     2 |
| f     |  50 |  51 |     3 |
| g     |  52 |  53 |     3 |
+-------+-----+-----+-------+
28 rows in set (0.00 sec)

I'm using CAST to enforce unique values in this case. I've tweaked the query many different ways, but I can't wrap my head around how to get the correct output. The order is as it should be, but the depth gets off track starting at item 'C,' and then it readjusts at item 'H.' The result I hope to achieve is (changes made to the depth column):

+-------+-----+-----+-------+
| title | lft | rgt | depth |
+-------+-----+-----+-------+
| I     |   1 |  24 |     0 |
| A     |   2 |  13 |     1 |
| 1     |   3 |   4 |     2 |
| 2     |   5 |  12 |     2 |
| a     |   6 |   7 |     3 |
| b     |   8 |   9 |     3 |
| c     |  10 |  11 |     3 |
| B     |  14 |  45 |     1 |
| C     |  16 |  23 |     1 |
| 3     |  17 |  18 |     2 |
| 4     |  19 |  20 |     2 |
| 5     |  21 |  22 |     2 |
| II    |  25 |  34 |     0 |
| D     |  26 |  27 |     1 |
| E     |  28 |  31 |     1 |
| 6     |  29 |  30 |     2 |
| F     |  32 |  33 |     1 |
| III   |  35 |  56 |     0 |
| G     |  36 |  45 |     1 |
| 7     |  37 |  42 |     2 |
| d     |  38 |  39 |     3 |
| e     |  40 |  41 |     3 |
| 8     |  43 |  44 |     2 |
| H     |  46 |  55 |     1 |
| 9     |  47 |  48 |     2 |
| 10    |  49 |  54 |     2 |
| f     |  50 |  51 |     3 |
| g     |  52 |  53 |     3 |
+-------+-----+-----+-------+

Once this is running correctly, I'll use the comments from Generate Nested UL's Based Upon Variable Depth Data to reconstruct the output. Thanks for your eyes and help!

Was it helpful?

Solution

I stared at my hand-drawn nested chart for two days. I even made a nice graphic for the world to [hopefully] help me with my problem. And I even copied my glaring error into the image file.

Item 'B' should have been {14,15}, not {14,45}. This is why the nest returned to normal at item 'H' {46,55}. My wife always says my handwriting's bad, and I leave to you a sheepish first post...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top