Как ВЫБРАТЬ непосредственных детей и предков все в том же запросе

Я работаю с древовидной структурой в MySQL, который является respresented использование вложенной модели наборов.

Я надеюсь, что некоторые из Вас sql эксперты могут помочь мне с созданием Запроса Select.

Я хотел бы смочь соответствовать ряду узлов, использующих КАК. Для каждого узла, который подобран, мне также нужны список запятой-delimmited предков того узла и список запятой-delimmited непосредственных детей того узла.

Я не действительно уверен, где запустить с этого - если такая вещь даже возможна в едином запросе. (В настоящее время я выполняю это с запросом в цикле.), На что я надеюсь, набор результатов, который мог бы выглядеть примерно так....

При запуске со строки "qu" и запросах Таблицы "Тело" я добираюсь...

Node      | Parent Nodes               | Immediate Children
Quads       Leg, Lower Body, Muslces     Vastus Lateralus, Vastus Medialis, Rectus Femoris
Obliques    Core, Trunk, Muscles         Inner obliques, outer obliques

Любые предложения о том, как выполнить это без запросов цикличного выполнения, очень ценились бы.

6
задан Travis 23 February 2010 в 14:38
поделиться

4 ответа

Хотя я согласен с никфом в том, что это плохо и грязно, это все равно весело, так что здесь:

SELECT     base.left_id, base.ancestors, 
           GROUP_CONCAT(children.left_id) children
FROM       (
            SELECT     base.left_id
            ,          GROUP_CONCAT(ancestors.left_id) ancestors
            FROM       nested_set   base
            LEFT JOIN  nested_set   ancestors
            ON         base.left_id     BETWEEN ancestors.left_id 
                                            AND ancestors.right_id
            WHERE      base.name  LIKE '%criteria%'
            GROUP BY   base.left_id
           ) base                                    
LEFT JOIN  nested_set   children
ON         children.left_id BETWEEN base.left_id 
                                AND base.right_id
LEFT JOIN  nested_set   inbetween
ON         inbetween.left_id BETWEEN base.left_id 
                                AND base.right_id
AND        children.left_id  BETWEEN inbetween.left_id 
                                AND inbetween.right_id     
WHERE      inbetween.left_id IS NULL
GROUP BY   base.left_id

По сути, трюк состоит в том, чтобы решить это в два этапа: во-первых, решить проблему предков и раздавить предков, чтобы список с, затем используйте этот результат, чтобы решить его для детей.

Предки относительно просты, это подзапрос в предложении from моего решения. Детям посложнее. Он работает, беря всех потомков, а затем требуя, чтобы не существовало никаких узлов между базовым узлом и потомками, что в основном ограничивает потомков только потомками.

Существуют и другие варианты этой стратегии для решения этой проблемы - например, вы можете сначала выполнить дочерние задачи, а затем решить предков, используя подзапрос в списке SELECT .

0
ответ дан 18 December 2019 в 04:52
поделиться

В одном запросе? Я бы не стал беспокоиться. SQL был бы ужасным и, вероятно, даже не таким эффективным. Разделите каждый бит на логические более мелкие запросы: сначала найдите все подходящие узлы, а затем для каждого из них дополнительную информацию, которая вам нужна.

0
ответ дан 18 December 2019 в 04:52
поделиться

Я не уверен на 100%, что вы хотите, но если я правильно понимаю, вы можете достичь этого, используя нормализованную схему базы данных и подзапросы.

Например:

Таблица "nodes" Таблица "node_parents"

Таблица "nodes" будет хранить все узлы, а "node_parents" будет отображать отношения между различными узлами.

Таким образом, при выборе LIKE определенного узла вы можете получить всех его родителей и детей из node_parents.

Дополнительную информацию можно получить с помощью объединений или подзапросов.

0
ответ дан 18 December 2019 в 04:52
поделиться

Этот вопрос намного сложнее, чем я ожидал в другом вашем сообщении, но я не согласен с первым ответом, изложенным на плакате.

Я совершенно уверен, что это возможно с помощью одного запроса.

Вам нужно использовать ПОДПРОСЫ и выбирает. Вы когда-нибудь смотрели действительно хорошую демонстрацию на сайте mySQL о модели списка смежности.

Поскольку вы можете LIKE для «узла», вы можете затем использовать подзапросы для вашего SQL-запроса, чтобы получить всех родителей и родителя. Один из моих запросов, по которому я сделал что-то вроде этого, был очень массивным! Но это сработало.

Взгляните: http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

Это небольшой фрагмент кода, который показывает, как немедленно дети найдены.

SELECT node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth
FROM nested_category AS node,
    nested_category AS parent,
    nested_category AS sub_parent,
    (
        SELECT node.name, (COUNT(parent.name) - 1) AS depth
        FROM nested_category AS node,
        nested_category AS parent
        WHERE node.lft BETWEEN parent.lft AND parent.rgt
        AND node.name = 'PORTABLE ELECTRONICS'
        GROUP BY node.name
        ORDER BY node.lft
    )AS sub_tree
WHERE node.lft BETWEEN parent.lft AND parent.rgt
    AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
    AND sub_parent.name = sub_tree.name
GROUP BY node.name
HAVING depth <= 1
ORDER BY node.lft
0
ответ дан 18 December 2019 в 04:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: