我有一个层次结构作为嵌套集存储在 mySQL 数据库中,我想找到一个节点的所有父节点,我可以这样做:
SELECT id FROM nested_set WHERE 837461 BETWEEN lft AND rgt;
但我想对可能有大量节点(比如 10,000)执行此操作。我可以通过将一组 BETWEEN 链接在一起来做到这一点,例如
SELECT id FROM nested_set WHERE
44102 BETWEEN lft AND rgt OR
837461 BETWEEN lft AND rgt OR
164462 BETWEEN lft AND rgt OR
566562 BETWEEN lft AND rgt OR
768916 BETWEEN lft AND rgt OR
...
但这看起来很乏味,我猜可能会超过 SQL 语句的大小。有没有比使用 10,000 个链式 OR 语句创建查询更有效的方法?
最佳答案
我不确定这是否符合改进或解决方案的条件,但我会试一试:正如我已经评论过的,您可以使用存储节点的临时表。
CREATE TEMPORARY TABLE nodes
(node integer,
INDEX (node));
INSERT INTO nodes
(node)
VALUES (44102),
(837461),
(164462),
(566562),
...;
然后您可以使用它通过内部联接执行您的SELECT
。
SELECT ns.id
FROM nested_set ns
INNER JOIN nodes n
ON n.node BETWEEN ns.lft
AND ns.rgt);
请注意,如果节点不是唯一的或多个给定节点在同一范围内,您可能需要使用 DISTINCT
。
另一种方法是使用 EXISTS
。
SELECT ns.id
FROM nested_set ns
WHERE EXISTS (SELECT *
FROM nodes n
WHERE n.node BETWEEN ns.lft
AND ns.rgt);
临时表上的索引可能支持性能。对于表 nested_set
,我会尝试在 (lft, rgt, id)
、(lft, rgt)
或至少 上建立索引(左)
。
当然你也可以使用UNION ALL
的派生表
...
(SELECT 44102 node
UNION ALL
SELECT 837461 node
UNION ALL
SELECT 164462
UNION ALL
SELECT 566562
...) nodes
...
从中加入或选择存在。但是那样的话就没有临时表中的支持索引了。然而,对于较小的集合,该索引可能没有那么大的权重。
关于mysql - SQL 多个由 or 连接的 between,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57237169/