繁体   English   中英

如何获取树结构中节点的所有子节点? SQL 查询?

[英]How to get all children of a node in tree structure ? SQL query?

表 - 用户

列 - (userId,name, managerId)

行 -

(1,nilesh,0)
(2,nikhil,1)    
(3,nitin ,2)  
(4,Ruchi,2)

如果我提供用户 ID,它应该列出所有向他报告的人。 如果我给 userId = 2 它应该返回 3,4。

这个查询是否正确

SELECT ad3.userId
FROM user au , user  au2 , user  au3
WHERE 
    ad.managerId = ad2.managerId AND 
    ad3.managerId = ad2.userId AND
    ad.userId=2

有没有有效的方法来管理数据库中的树结构? 左右叶方式怎么样?

我使用文本字段来处理 SQL 中的树。 它比使用左/右值更容易。

让我们以 MySQL 文章中的示例为例:

+-----------------------+
| name                  |
+-----------------------+
| ELECTRONICS           |
|  TELEVISIONS          |
|   TUBE                |
|   LCD                 |
|   PLASMA              |
|  GAME CONSOLES        |
|  PORTABLE ELECTRONICS |
|   MP3 PLAYERS         |
|    FLASH              |
|   CD PLAYERS          |
|   2 WAY RADIOS        |
|    FRS                |
+-----------------------+

它会产生一个像这样的表:

Id      ParentId        Lineage     Name

1       null            /1/         ELECTRONICS
2       1               /1/2/       TELEVISIONS
3       2               /1/2/3/     TUBE
4       2               /1/2/4/     LCD
5       2               /1/2/5/     PLASMA
6       6               /1/6/       GAME CONSOLES
7       1               /1/7/       PORTABLE ELECTRONICS
8       7               /1/7/8/     MP3 PLAYERS
9       8               /1/7/8/9/   FLASH
10      7               /1/7/10/    CD PLAYERS
11      1               /1/11/      2 WAY RADIOS
12      11              /1/11/12/   FRS

找到所有您只需使用便携设备中的 Lineage 的便携设备:

SELECT * FROM theTable WHERE Lineage LIKE '/1/7/%'

缺点:

  • 您需要在每次 INSERT 到 append PK 到 Lineage 之后进行更新

建议:

我通常添加另一列,将路径作为文本放入(例如'electronics/televisions/tube'

像这样的东西(ANSI SQL):

WITH RECURSIVE emptree (userid, name, managerid) AS (
    SELECT userid, 
           name, 
           managerid
    FROM the_table 
    WHERE userid = 2

    UNION ALL

    SELECT c.userid, 
           c.name,
           c.managerid
    FROM the_table c
       JOIN emptree p ON p.userid = c.managerid
)
SELECT *
FROM emptree

在我看来,邻接表 model 的问题在于它很难在 SQL 中处理,尤其是当您不知道树结构的嵌套深度时。

您提到的“左右叶方式”可能是嵌套集 model 并允许您存储这样的东西

LFT   RGT   Name
1     8      nilesh
2     7      nikhil
3     4      nitin
5     6      Ruchi

然后你可以简单地找到任何人的所有下属

SELECT Name FROM Hierarchy WHERE LFT BETWEEN @LFT AND @RGT

我认为查询更容易处理,但树修改更难。 如果您的数据没有太大变化,那么我认为这是一个更好的解决方案。 (虽然不是每个人都会同意我的观点)

这里有一个很好的教程

对于这个问题,我有一个简单的答案:

表创建:

   Create Table #AllChilds(id int)

项目清单:

   Declare @ParentId int; 
   set @ParentId=(Select Id from Employee Where id=1)   
   -- Here put the id as the record for which you want all childs
   While(@ParentId is not null ) 
   begin 
   set @ParentId=(Select Id from Employee Where ParentId=@ParentId) 
   insert into #AllChilds values(@ParentId) 
   end 

查看结果:

   Select Id from #AllChilds 

清理:

Drop table #AllChilds
SELECT user.id FROM user WHERE user.managerid = 2

这是你想要的吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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