2016-02-01 7 views
0

Эта функция в настоящее время получает дочерний уровень категории один от родителя. Мы знаем родителя ($ category_id), он проверяет дочернюю категорию и возвращает результат правильно.Список всех категорий детей для родительской категории

// list category for the category (type) 
function getCategoryItemsList($category_id) { 

$cat_list = $category_id; 

// check for child category 
$sql = "select category_id from category where category_parent_id = $category_id "; 
$cat_ids = getSqlResult($sql, SQL_RESULT_ALL); 

foreach($cat_ids as $item) { 
$cat_list = $cat_list . ',' . $item['category_id']; 
} 
return $cat_list; 
} 

Проблема, когда у нас есть несколько уровней категорий, как:

родительского> ребенок> внучатого ребенок> двоюродного внучатого ребенок

Как я могу вернуть все уровни ребенка категории родителей ?

///// MYSQL CATEGORY DB 
category_id category_name   category_parent_id 
1    shoes     0 
2    blue shoes    1 
3    men blue shoes   2 
4    men blue shoe small 3 
5    red shoes    1 
6    men red shoes   5 
7    shirts     0 

Ожидаемый результат при $ category_id = «1» будет 2,3,4,5,6

+0

Какую БД вы используете? Кстати, я постараюсь сделать это на уровне БД. – MaxU

+0

db - mysql. –

+0

Я думаю, это именно то, что вы ищете: http://dba.stackexchange.com/questions/30021/mysql-tree-hierarchical-query – MaxU

ответ

0

Лучшее (возможно только), как я знаю, если вам нужно получить всех родителей или дети в таблице с древовидной родительской/дочерней структурой произвольной высоты имеют рекурсивный запрос. Сначала это может быть немного сложно понять, но это отличное упражнение и увлекательное, когда вы его заработаете. Здесь есть объяснение и пример: https://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx

EDIT: Возможно, что-то концептуально неправильно с тем, что вы просите. Я предполагаю, что категория может иметь более одного ребенка, запрос не может «знать», какой ребенок выбрать, и, следовательно, выберет все из них. В вашем примере есть только один дочерний pr. и в этом случае запрос работает, но вы должны помнить об этом предположении. Однако довольно просто выбрать родительский элемент для каждой категории в запросе ниже. Это мое предложение:

BEGIN 
WITH ct 
AS (
    SELECT c1.Id, 
     0 Step, 
     c1.ParentCategoryId 
    FROM _Category c1 
    WHERE c1.Id = 132 

    UNION ALL 

    SELECT c2.Id, 
     ct.Step + 1, 
     c2.ParentCategoryId 
    FROM _Category c2 
    JOIN ct 
     ON c2.ParentCategoryId = ct.Id 
    ) 
SELECT ct.Id, 
    ct.Step 
FROM ct; 
END 
+0

Я действительно создал этот точный запрос в функции на работе недавно, но сейчас я не на компьютере, поэтому я не могу опубликовать его ... –

+0

Можете ли вы опубликовать его, когда сможете? –

+0

Опубликовано! :) BTW - это MS SQL, и я не проверял, возможна ли эта форма рекурсии в MySQL, но я думаю, что стоит попробовать. Далее - должна быть указана максимальная рекурсия, но без петель в вашей структуре таблицы это нормально. –

1

Попробуйте это:

create table category(
    id  int, 
    name  varchar(100), 
    parent_id int 
); 

insert into category values 
    (1, 'shoes', 0), 
    (2, 'blue shoes', 1), 
    (3, 'men blue shoes', 2), 
    (4, 'men blue shoe small', 3), 
    (5, 'red shoes', 1), 
    (6, 'men red shoes', 5), 
    (7, 'shirts', 0); 

SELECT GROUP_CONCAT(lv SEPARATOR ',') FROM (
SELECT @pv:=(SELECT GROUP_CONCAT(id SEPARATOR ',') FROM category WHERE 
FIND_IN_SET(parent_id, @pv)) AS lv FROM category 
JOIN (SELECT @pv:=1)tmp 
WHERE parent_id IN (@pv)) a; 

Выход:

mysql> SELECT GROUP_CONCAT(lv SEPARATOR ',') FROM (
    -> SELECT @pv:=(SELECT GROUP_CONCAT(id SEPARATOR ',') FROM category WHERE 
    -> FIND_IN_SET(parent_id, @pv)) AS lv FROM category 
    -> JOIN (SELECT @pv:=1)tmp 
    -> WHERE parent_id IN (@pv)) a; 
+--------------------------------+ 
| GROUP_CONCAT(lv SEPARATOR ',') | 
+--------------------------------+ 
| 2,5,3,6,4      | 
+--------------------------------+ 
1 row in set (0.00 sec) 

SQLFiddle demo

Это решение основано на that answer

+0

Похоже, что он идет по правильному пути! Как бы вы обновили функцию выше (getCategoryItemsList), чтобы использовать новый запрос, который вы написали? –

+0

Как получить результаты в строке, например ... string (11) "2,5,3,6,4" –