SQL获取最低级别的子节点和根节点

时间:2016-01-22 13:24:12

标签: sql hierarchical-data recursive-query

我有数据库架构:[Id],[ParrentId],[更多表格]

我的层次结构如下:

1. a
 2. aa
  3. aaa_1
  3. aaa_2
1. b
 2. bb
1. c
 2. cc
  3. ccc_1
   4. cccc
  3. ccc_2

我想要一个(select * where X)=> [X,最低级别的孩子]喜欢: [a,aaa_1] [a,aaa_2]; [cc,cccc]等。

我可以通过

获得最低的孩子
SELECT t1.name FROM
category AS t1 LEFT JOIN category as t2
ON t1.category_id = t2.parent
WHERE t2.category_id IS NULL;

但我不知道如何将其与根节点连接。

2 个答案:

答案 0 :(得分:1)

假设:

  • DBMS是SQL Server;
  • 树的最高级别节点具有parent = NULL;
  • 你想要所有树木的最低叶子,而不仅仅是树根;
  • 您希望所有节点都处于最低级别,而不仅仅是一个;

此查询可以执行此操作:

WITH r ( category_id, name, root, depth )
-- finds the root relationship
AS (
    SELECT category_id, name, category_id, 0
        FROM category
        -- WHERE parent IS NULL -- this would only look at root nodes
    UNION ALL
    SELECT c.category_id, c.name, r.root, r.depth + 1
        FROM r
        JOIN category c
            ON c.parent = r.category_id
), s ( category_id, name, root, window_id )
-- finds the lowest leaves
AS (
    SELECT category_id, name, root, RANK() OVER(partition by root order by depth DESC)
        FROM r
)
SELECT c.name AS NodeName, s.Name AS DeepLeafName
    FROM category c
    JOIN s
        ON c.category_id = s.root
        WHERE s.window_id = 1;

以下是结果集:

result set

答案 1 :(得分:0)

使用SQL Server,您可以尝试:

With CTE as 
(
Select ID as Child, lev = 1
from category
where ID = X
UNION ALL
Select category.ID, CTE.lev + 1
from category
    inner join CTE ON category.ParentID = CTE.Child
)

select CTE_1.Child, CTE_2.Child 
from CTE as CTE_1 
    inner join CTE as CTE_2
where CTE_1.lev  = 1 AND CTE_2.lev = (select MAX(CTE.lev) from CTE)