希望你们中的一些 mysql 专家可以帮助我。
我有存储在嵌套集中的搜索标签数据。
TABLE searchTags
searchTagID
searchTag
lft
rgt
(我使用嵌套集是因为有时我需要轻松地选择树的整个分支。)
我想构建一个查询,该查询将返回与 LIKE 匹配的节点的结果集、这些节点中每一个的祖先以及这些节点中每一个的直接子节点。
例如,如果这是我的嵌套集...
1_tagA_22
2_tagB1_11 12_tagB2_13 14_tagB3_21
3_taC1_4 5_taC2_10 15_tagC3_20
6_tagD1_9 16_tagD2_17 18_tagD3_19
7_tagE1_8
...对于我的搜索针,我有 LIKE CONCAT('%','tagc','%'),我想返回如下所示的内容:
searchTag | ancestors | immediateChildren
tagC1 tagB1,tagA NULL
tagC2 tagB1,tagA tagD1
tagC3 tagB3,tagA tagD2,tagD3
我目前正在使用多个查询来执行此操作。首先,我选择搜索标签及其祖先的结果集。然后我遍历这个结果集,对于每个结果,我做另一个选择来获得直接的 child 。 (我在下面包括了这些查询,以供引用。)
这个方法可行,但我感觉它是一个低效的解决方案,而且迟早会失败。 :) 我想知道是否有更好的方法来执行此操作 - 即是否有一种方法可以将所有这些组合到一个更有效的 SELECT 语句中?
如有任何建议,我们将不胜感激。
谢谢!
引用: 我使用以下内容来选择搜索标签和祖先的路径...
SELECT
node.searchTag,
GROUP_CONCAT(parent.searchTag
ORDER BY parent.lft DESC
SEPARATOR '; ') AS ancestors
FROM
searchTags AS node,
searchTags AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
AND parent.lft < node.lft
AND node.searchTag LIKE CONCAT('%','tagc','%')
GROUP BY node.searchTagID;
...然后我遍历此结果集并为每个结果运行另一个查询以获取直接子项(使用 mrbinky3000 的出色方法):
SELECT lft, rgt INTO @parent_left, @parent_right FROM searchTags WHERE searchTagID = $id;
SELECT
GROUP_CONCAT(child.searchTag SEPARATOR "; ") as searchTag
FROM searchTags AS child
LEFT JOIN searchTags AS ancestor ON
ancestor.lft BETWEEN @parent_left+1 AND @parent_right-1 AND
child.lft BETWEEN ancestor.lft+1 AND ancestor.rgt-1
WHERE
child.lft BETWEEN @parent_left+1 AND @parent_right-1 AND
ancestor.searchTagID IS NULL;
最佳答案
Here是一个带有解决方案的 SQL Fiddle。
SQL 是:
SELECT t0.title node
,GROUP_CONCAT(t5.title) children
,(SELECT GROUP_CONCAT(t6.title)
FROM Tree t6
WHERE t6.lft<t0.lft AND t6.rgt>t0.rgt
ORDER BY t6.lft) ancestors
FROM Tree t0
LEFT JOIN
(SELECT *
FROM (SELECT t1.lft node
,MAX(t2.lft) nodeparent
FROM Tree t1
INNER JOIN
Tree t2 ON t1.lft>t2.lft AND t1.rgt<t2.rgt
GROUP BY t1.lft) t3
LEFT JOIN
Tree t4 ON t3.node=t4.lft) t5 ON t0.lft=t5.nodeparent
GROUP BY t0.title;
祖先是 select 语句中非常简单的子查询。
对于 child ,子查询 t3 通过查找具有 MAX(lft) 的每个节点的祖先来创建邻接列表,然后将其连接到 t4 以获得 child 的名字。
请随意将您喜欢的任何 WHERE
子句放在底部。
关于mysql - 使用 MYSQL 在嵌套集树中选择节点的祖先和直接子节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2248650/