Search code examples
mysqlsqlsql-order-bynested-sets

Get nested set ancestor where condition


Given a nested set in mysql like this

+-------------+----------------------+-----+-----+------+
| category_id | name                 | lft | rgt | rank |
+-------------+----------------------+-----+-----+------+
|           1 | ELECTRONICS          |   1 |  20 |  99
|           2 | TELEVISIONS          |   2 |   9 |  50
|           3 | TUBE                 |   3 |   4 |  25
|           4 | LCD                  |   5 |   6 |  25
|           5 | PLASMA               |   7 |   8 |  25
|           6 | PORTABLE ELECTRONICS |  10 |  19 |  50
|           7 | MP3 PLAYERS          |  11 |  14 |  25
|           8 | FLASH                |  12 |  13 |  10
|           9 | CD PLAYERS           |  15 |  16 |  25
|          10 | 2 WAY RADIOS         |  17 |  18 |  20

How can I get an ancestor for e.g: "Flash" where condition rank is >=50 AND <= 99 LIMIT 1 sorted by lft DESC. so the result will be

+-------------+----------------------+-----+-----+------+
| category_id | name                 | lft | rgt | rank |
+-------------+----------------------+-----+-----+------+
|           6 | PORTABLE ELECTRONICS |  10 |  19 |  50

for visualization refer to this link http://mikehillyer.com/media//categories.png


Solution

  • sql fiddle is not working for me right now, but you should be able to do something like this.

    SELECT  
        c2.* 
    FROM
        Categories as c1
        INNER JOIN Categories as c2 ON 
                c1.`lft` >= c2.lft AND c1.`lft` <= c2.`rgt` 
                AND c2.`RANK` >=50 AND c2.`RANK` <= 99 
    WHERE 
        c1.`category_id` = 8
    ORDER BY 
        c2.`lft` DESC
    LIMIT 1;
    

    SQL Fiddle