小编典典

深度嵌套的子查询,用于遍历MySQL中的树

sql

我的数据库中有一个表,其中使用混合嵌套集(MPTT)模型(具有lft和的rght值)和邻接列表模型(存储parent_id在每个节点上)存储树结构。

my_table (id, parent_id, lft, rght, alias)

这个问题与树的任何MPTT方面都不相关,但是我想我将其保留,以防万一有人对如何利用它有个好主意。

我想将别名的路径转换为特定的节点。例如:"users.admins.nickf"将找到别名为“ nickf”的节点,该节点是别名为“
admins”的节点的子节点,别名为“ users”的根节点。上有一个唯一索引(parent_id, alias)

我首先编写函数,以便将路径拆分为各个部分,然后一个一查询数据库:

SELECT `id` FROM `my_table` WHERE `parent_id` IS NULL AND `alias` = 'users';-- 1
SELECT `id` FROM `my_table` WHERE `parent_id` = 1 AND `alias` = 'admins';   -- 8
SELECT `id` FROM `my_table` WHERE `parent_id` = 8 AND `alias` = 'nickf';    -- 37

但是后来我意识到,使用可变数量的嵌套,我可以通过一个查询来做到这一点:

SELECT `id` FROM `my_table` WHERE `parent_id` = (
    SELECT `id` FROM `my_table` WHERE `parent_id` = (
        SELECT `id` FROM `my_table`
        WHERE `parent_id` IS NULL AND `alias` = 'users'
    ) AND `alias`  = 'admins'
) AND `alias` = 'nickf';

由于子查询的数量取决于路径中的步骤数,因此我是否会遇到 子查询过多的 问题?(如果有这样的事情)

有没有更好/更智能的方法来执行此查询?


阅读 186

收藏
2021-04-28

共1个答案

小编典典

这行得通吗?

select r0.id 
  from my_table as r0 
  join my_table as r1 on(r0.parent_id = r1.id) 
  join my_table as r2 on(r1.parent_id = r2.id)
 where r0.alias='nickf'
   and r1.alias='admins'
   and r2.alias='users'
   and r2.parent_id is null

在我看来,实际上并不需要嵌套的子查询。

还是我错了,错过了什么?

2021-04-28