简体   繁体   中英

SQL: Getting immediate subordinates of node in nested set

I'm using this article as a guide to create a database tree structure using the nested set model. However, I can't get it to work: when I execute the following query:

SELECT node.name, (COUNT(parent.name) - 1) AS depth
FROM nested_category AS node,
        nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft;

I get this error:

#1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and
contains nonaggregated column 'test.node.lft' which is not
functionally dependent on columns in GROUP BY clause; this is 
incompatible with sql_mode=only_full_group_by

Someone in the comments of that article suggested to group by ID instead of name, so I replaced GROUP BY node.name by GROUP BY node.category_id and that works.

However, some of the other queries in the article still don't work. I'd like to select the immediate children of a node, for example:

SELECT node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth
FROM nested_category AS node,
        nested_category AS parent,
        nested_category AS sub_parent,
        (
                SELECT node.name, (COUNT(parent.name) - 1) AS depth
                FROM nested_category AS node,
                        nested_category AS parent
                WHERE node.lft BETWEEN parent.lft AND parent.rgt
                        AND node.name = 'PORTABLE ELECTRONICS'
                GROUP BY node.name
                ORDER BY node.lft
        )AS sub_tree
WHERE node.lft BETWEEN parent.lft AND parent.rgt
        AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
        AND sub_parent.name = sub_tree.name
GROUP BY node.name
HAVING depth <= 1
ORDER BY node.lft;

But I can't get it to work, because I have no idea how it works (nor where to start). Could someone please explain how to understand these queries, maybe step by step?

I'm using MySQL Ver 14.14 Distrib 5.7.17.

Thanks a lot!
Pieter

Hi I am using the same query and it is working fine for me.

SELECT node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth
FROM nested_category AS node,
    nested_category AS parent,
    nested_category AS sub_parent,
    (
            SELECT node.name, (COUNT(parent.name) - 1) AS depth
            FROM nested_category AS node,
                    nested_category AS parent
            WHERE node.lft BETWEEN parent.lft AND parent.rgt
                    AND node.id= 36
            GROUP BY node.name
            ORDER BY node.lft
    )AS sub_tree
WHERE node.lft BETWEEN parent.lft AND parent.rgt
    AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
    AND sub_parent.name = sub_tree.name
GROUP BY node.name
HAVING depth = 1
ORDER BY node.lft;

Instead of node.name is used node.id and changed HAVING depth <= 1 to = 1, since I don't want to display the head node.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM