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

Nee*_*lpe 6 sql database tree

表 - 用户

列 - (userId,name,managerId)

行 -

(1,nilesh,0)
(2,nikhil,1)    
(3,nitin ,2)  
(4,Ruchi,2)
Run Code Online (Sandbox Code Playgroud)

如果我给用户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
Run Code Online (Sandbox Code Playgroud)

在DB中管理树结构有什么有效的方法吗?右叶和左叶怎么样?

jga*_*fin 13

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

让我们从MySQL文章中获取示例:

+-----------------------+
| name                  |
+-----------------------+
| ELECTRONICS           |
|  TELEVISIONS          |
|   TUBE                |
|   LCD                 |
|   PLASMA              |
|  GAME CONSOLES        |
|  PORTABLE ELECTRONICS |
|   MP3 PLAYERS         |
|    FLASH              |
|   CD PLAYERS          |
|   2 WAY RADIOS        |
|    FRS                |
+-----------------------+
Run Code Online (Sandbox Code Playgroud)

它会产生如下表格:

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
Run Code Online (Sandbox Code Playgroud)

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

SELECT * FROM theTable WHERE Lineage LIKE '/1/7/%'
Run Code Online (Sandbox Code Playgroud)

缺点:

  • 每次INSERT后都需要执行UPDATE以将PK附加到Lineage

建议:

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

  • 你在SQL中用通配符和比较数字来运行查询.通配符的查询将花费更多的时间.所有孩子的检索时间更长.我第一次采取像你这样的方法,但效率并不高. (2认同)

a_h*_*ame 9

像这样的东西(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
Run Code Online (Sandbox Code Playgroud)

  • 但只有树不经常变化. (4认同)
  • @David Steele:绝对的.但了解所有选项总是好的;) (2认同)

Dav*_*ele 9

在我看来,邻接列表模型的问题在于它很难在SQL中处理,尤其是当您不知道树结构的嵌套程度有多深时.

你提到的"左右叶子方式"可能是嵌套的集合模型,允许你存储这样的东西

LFT   RGT   Name
1     8      nilesh
2     7      nikhil
3     4      nitin
5     6      Ruchi
Run Code Online (Sandbox Code Playgroud)

然后你可以简单地找到所有下属

SELECT Name FROM Hierarchy WHERE LFT BETWEEN @LFT AND @RGT
Run Code Online (Sandbox Code Playgroud)

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

这里有一个非常好的教程