Надеюсь, что некоторые из вас, эксперты 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
В настоящее время я делаю это с несколькими запросами. Сначала я выбираю набор поисковых тегов и их предков. Затем я перебираю этот набор результатов и для каждого результата делаю другой выбор, чтобы получить непосредственных детей. (Я включаю эти запросы ниже, для справки.)
Этот метод работает, но я чувствую, что это неэффективное решение, которое может взорваться рано или поздно. :) Мне интересно, есть ли лучший способ сделать это - то есть, есть ли способ объединить все это в одном операторе 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;