2012-05-08 3 views
3

У меня есть смежности модовой структуры списка, как этотИзменение в запросе на выборку

enter image description here

этим запросом

SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4 
FROM category AS t1 
LEFT JOIN category AS t2 ON t2.parent = t1.category_id 
LEFT JOIN category AS t3 ON t3.parent = t2.category_id 
LEFT JOIN category AS t4 ON t4.parent = t3.category_id 
WHERE t1.name = 'ELECTRONICS'; 

получать результат, как этот

enter image description here

, но я хочу чтобы получить такой результат, есть вариант пу делает это

enter image description here

заранее спасибо

+0

Ключевое слово 'UNION' может быть направлено вправо: http://dev.mysql.com/doc/refman/5.1/en/union.html – Quasdunk

+0

Я хочу рассчитать всю категорию под категорией ELECTRONICS –

+0

@vikastyagi Итак, из приведенных выше результатов все, что вам действительно нужно, это '19'? – DaveRandom

ответ

0

Вы можете сделать что-то вроде этого:

SELECT name FROM category WHERE name = 'ELECTRONICS' 

UNION 

SELECT t2.name FROM t2 INNER JOIN category as t1 ON t2.parent = t1.category_id WHERE t1.name = 'ELECTRONICS' 

UNION 

SELECT t3.name FROM t3 INNER JOIN category as t1 ON t3.parent = t1.category_id WHERE t1.name = 'ELECTRONICS' 

UNION 

SELECT t4.name FROM t4 INNER JOIN category as t1 ON t4.parent = t1.category_id WHERE t1.name = 'ELECTRONICS' 
+1

Вы немного правы, но из-за иерархии вложенных уровней вам не хватало бы многих элементов, поскольку «Plasma», «LCD» и «Tube» находятся под «TELEVISION», который находится под «ELECTRONICS» – DRapp

1

К сожалению, трудно подсчитать количество подразделов категории с вашим текущая настройка. Мало того, что глубина вашего меню ограничена суммой LEFT JOIN, которую вы добавляете, также невозможно определить, какие категории напрямую связаны с категорией более одного уровня.

Отличное решение этой проблемы - использование структуры для вашего меню, you can read more here. Больше объяснений, как это сделать с помощью mysql here.

1

Вам понадобится UNION, и я предлагаю удалить дубликаты записей на их соответствующих уровнях. Кроме того, нет необходимости включать значения «NULL», если ваше намерение состоит в том, чтобы представить пользователям, как и в веб-приложениях ...

select L1.Category_ID, 
     L1.name, 
     "1" as HierarchyLevel, 
     count(L2.Category_ID) as NextLevelCount 
    from Category L1 
     LEFT JOIN Category L2 
      on L1.Category_ID = L2.Parent 
    where L1.name = "ELECTRONICS" 
    group by L1.Category_ID 
UNION 
select L2.Category_ID, 
     L2.name, 
     "2" as HierarchyLevel, 
     count(L3.Category_ID) as NextLevelCount 
    from Category L1 
     JOIN Category L2 
      on L1.Category_ID = L2.Parent 
      LEFT JOIN Category L3 
       on L2.Category_ID = L3.Parent 
    where L1.name = "ELECTRONICS" 
    group by L2.Category_ID 
UNION 
select L3.Category_ID, 
     L3.name, 
     "3" as HierarchyLevel, 
     count(L4.Category_ID) as NextLevelCount 
    from Category L1 
     JOIN Category L2 
      on L1.Category_ID = L2.Parent 
      JOIN Category L3 
       on L2.Category_ID = L3.Parent 
       LEFT JOIN Category L4 
       on L3.Category_ID = L4.Parent 
    where L1.name = "ELECTRONICS" 
    group by L3.Category_ID 
UNION 
select L4.Category_ID, 
     L4.name, 
     "4" as HierarchyLevel, 
     1 as NextLevelCount 
    from Category L1 
     JOIN Category L2 
      on L1.Category_ID = L2.Parent 
      JOIN Category L3 
       on L2.Category_ID = L3.Parent 
       JOIN Category L4 
       on L3.Category_ID = L4.Parent 
    where L1.name = "ELECTRONICS" 

Это, очевидно, фиксируется на 4-х уровнях, но будет профсоюзу их в единый список, но не дубликатов, как вы представили. Я также придерживался уровня иерархии только для справочных целей. Чтобы получить подсчеты на каждом уровне, вы должны сделать LEFT JOIN на следующий уровень, в противном случае вы будете пропускать возможные предметы на уровне, который вы пытаетесь получить, но остальные ДОЛЖНЫ оставаться как INNER JOINs.

Если вы имеете дело с продуктами, я думаю, что если не после 4-х уровней глубоко они не могут найти что-то, что есть большая проблема :)

+0

спасибо за реле, вы дали мне правильный ответ, что я спросил, но все же у меня проблема, если уровень выше 4 –

+1

@vikastyagi, действительно ... более 4 уровней? Делая больше, я бы на самом деле написал хранимую процедуру для запроса данных. Не имея MySQL, где я нахожусь, не может сделать это на лету. Можете ли вы показать иерархию, которая будет глубже, чем 4 уровня? – DRapp

1

В качестве отправной точки интереса, потому что это может быть слишком много работа и отличные от того, что вы должны быть «ответом», я бы предложил вам изучить концепцию «Модифицированный предварительный траверс дерева». Там отличный explanation by Gijs Van Tulder.

Для хранения данных иерархии потребуются дополнительные поля, а дополнительный код для поддержки этой структуры, но он может сделать древовидные структуры намного проще в реляционной базе данных.

В основном, как и обычный parent_id, который мы храним с деревьями, мы также храним left и значение right. При правильном заполнении, тогда легко получить «всех детей узла», просто выбрав все узлы, где node.left > parent.left и node.right < parent.right, независимо от глубины узлов.

Смежные вопросы