我的数据库中有一个表,其中使用混合嵌套集(MPTT)模型(具有lft和的rght值)和邻接列表模型(存储parent_id在每个节点上)存储树结构。
lft
rght
parent_id
my_table (id, parent_id, lft, rght, alias)
这个问题与树的任何MPTT方面都不相关,但是我想我将其保留,以防万一有人对如何利用它有个好主意。
我想将别名的路径转换为特定的节点。例如:"users.admins.nickf"将找到别名为“ nickf”的节点,该节点是别名为“ admins”的节点的子节点,别名为“ users”的根节点。上有一个唯一索引(parent_id, alias)。
"users.admins.nickf"
(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';
由于子查询的数量取决于路径中的步骤数,因此我是否会遇到 子查询过多的 问题?(如果有这样的事情)
有没有更好/更智能的方法来执行此查询?
这行得通吗?
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
在我看来,实际上并不需要嵌套的子查询。
还是我错了,错过了什么?