mysql - SQL 多个之间由 or 连接
问题描述
我有一个层次结构作为嵌套集存储在 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)
或者至少(lft)
。
当然,您也可以使用UNION ALL
s 的派生表,例如
...
(SELECT 44102 node
UNION ALL
SELECT 837461 node
UNION ALL
SELECT 164462
UNION ALL
SELECT 566562
...) nodes
...
加入或从中选择存在。但是这样就没有临时表中的支持索引了。但是,对于较小的集合,该索引可能无论如何都没有那么大的权重。
推荐阅读
- c# - 在点网核心项目中使用点网实体框架类库构建
- oracle - 错误:使用 ITfoxtech Saml2 的“不完全有一个断言”
- python - 使用日期时间键在python中对字典进行排序和排列
- android - 如何使用不受缩放或缩放影响的画布在 ImageView 上绘制线条?
- java - 如果JVM具有该类的名称,为什么JVM不能创建包含main方法的类的对象以便从该类访问main方法?
- javascript - 交叉引用中修改的 const 变量
- reactjs - 如何在 ReactJS 挂钩中映射数据?
- angular - 如何将日期重置为新日期?
- eloquent - Lumen/Laravel Eloquent - 按数据透视表中的属性过滤
- excel - 当我运行我的 excel 宏并出现错误 5487(文件权限错误)时,我该怎么办?