MySQL parent -> дочерний запрос - PullRequest
0 голосов
/ 03 июня 2009

Я работаю с mySQL и нахожусь в ситуации, когда мне нужно выбрать данные из одной таблицы, которые соответствуют идентификатору на любом уровне в родительской -> дочерней иерархии данных в другой таблице.

Более того, я хотел бы решить эту проблему с помощью хорошо написанного SQL-запроса, а не рекурсивной функции в моем PHP-коде, так как эта функция будет использоваться совсем немного.

Я попытался выполнить поиск и наткнулся на многочисленные похожие проблемы (большинство из них решаются), однако ни одна из них не помогла мне.

Чтобы проиллюстрировать ситуацию, вот мои текущие настройки

Таблица «Статьи»:

  • article_id
  • category_id
  • ...

таблица категорий

  • category_id
  • parent_id
  • ...

Мне нужно выбрать все статьи из «статьи», где «article.category_id», скажем, 10. Но я также получаю все статьи из всех категорий из дерева, к которому принадлежит «category.category_id» 10.

Значение, где "10" - родитель и все его дети, и выше, где 10 - ребенок и все его родители.

Возможно без рекурсивной функции php?

Спасибо.

Ответы [ 4 ]

3 голосов
/ 03 июня 2009

Невозможно получить целое дерево в одном запросе с использованием используемого вами списка смежности, учитывая, что вы используете MySQL.

Некоторые другие бренды баз данных поддерживают расширения SQL для поддержки такого дизайна. Oracle, Microsoft SQL Server, IBM DB2 и PostgreSQL 8.4 (в настоящее время в бета-версии) поддерживают расширения SQL.

Существуют и другие модели баз данных, которые позволяют более эффективно запрашивать деревья. Этот вопрос неоднократно задавался в StackOverflow, в блогах и в статьях.

Вы также можете прочитать " Деревья и иерархии в SQL для умных " Джо Селко, в которых подробно рассматриваются несколько таких конструкций.

2 голосов
/ 03 июня 2009

Это можно сделать за MySQL, но это займет немного усилий. Вам нужно написать такую ​​функцию:

CREATE FUNCTION hierarchy_connect_by_parent_eq_prior_id(value INT) RETURNS INT
NOT DETERMINISTIC
READS SQL DATA
BEGIN
        DECLARE _id INT;
        DECLARE _parent INT;
        DECLARE _next INT;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET @id = NULL;

        SET _parent = @id;
        SET _id = -1;

        IF @id IS NULL THEN
                RETURN NULL;
        END IF;

        LOOP
                SELECT  MIN(id)
                INTO    @id
                FROM    categories
                WHERE   parent = _parent
                        AND id > _id;
                IF @id IS NOT NULL OR _parent = @start_with THEN
                        SET @level = @level + 1;
                        RETURN @id;
                END IF;
                SET @level := @level - 1;
                SELECT  id, parent
                INTO    _id, _parent
                FROM    categories
                WHERE   id = _parent;
        END LOOP;
END

и использовать его в запросе:

SELECT  id, parent, level
FROM    (
        SELECT  hierarchy_connect_by_parent_eq_prior_id(id) AS id, @level AS level
        FROM    (
                SELECT  @start_with := 0,
                        @id := @start_with,
                        @level := 0
                ) vars, categories 
        WHERE   @id IS NOT NULL
        ) ho
JOIN    categories hi
ON      hi.id = ho.id

См. Эту запись в моем блоге для более подробной информации:

1 голос
/ 03 июня 2009

Самым распространенным шаблоном для хранения иерархических данных в реляционной базе данных является либо соседний список, либо модифицированный предварительный порядок (он же вложенный набор) . Альтернативой является использование материализованного пути, который в основном представляет собой механизм кэширования, расположенный поверх соседнего списка. См. Также в этой таблице для сравнения плюсов и минусов .

0 голосов
/ 03 июня 2009

Я не знаю, насколько это вам поможет, но я написал небольшую функцию, которая генерирует иерархическое дерево, используя один запрос MySQL. По сути, вся важная логика перенесена в PHP. Мое решение использует модель списка смежности, а затем использует ссылки PHP для построения древовидной структуры данных с помощью плоской структуры. Посмотрите на суть ниже и посмотрите, есть ли у вас вдохновение. Я помог бы вам больше, но есть некоторые проблемы, с которыми мне приходится сталкиваться на работе.

http://gist.github.com/104357

...