2011-01-23 2 views
2

У меня есть categories таблицу, которая выглядит следующим образом:Как объединить эти 2 таблицы вместе (MySQL, Иерархический запрос)?

id | name  | parent  
-----------------------  
1 | Toys  | 1 
2 | Clothing | 1 
3 | Kid's Toys | 0 

Я еще одна таблица называется category_relationships, который выглядит следующим образом:

id | category_id | parent_id  
----------------------------  
1 | 3   | 1 

Я хочу иметь следующий вывод:

Категории :

Toys 
    - Kid's Toys 
Clothing 

Как достичь этого с помощью одного запроса?

+2

Иерархический запрос - ouch ... будет жестким. Если вы не знаете максимальную глубину иерархии спереди, вы не можете закодировать общее решение, если только СУБД не поддерживает предложение WITH WITH RECURSIVE (или нестандартные расширения, такие как «CONNECT BY»). –

+0

Да, знаете ли вы максимальную глубину дерева? – Xailor

ответ

0

Лучше/надлежащей/надежный ответ, вероятно, будет создать процедуру MySQL для этого, но если ваши данные могут вписываться в эти ограничения, вы не можете использовать ниже:

  • не более 5 уровней (или расширить шаблон в соответствии с требованиями)
  • идентификаторов не более чем 6 цифр (или изменить выражение Concat)

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

select concat(1000000 + a.id, '|') SORT 
      ,a.name 
    from categories a 
    where a.parent = 1 # top level parents only 
union all 
    select concat(1000000 + a.id, '|', 
      1000000 + IFNULL(b.id,0), '|') 
      ,concat(' - ', b.name) 
    from categories a 
    inner join category_relationships a1 on a1.parent_id = a.id 
    inner join categories b on b.id = a1.category_id 
    where a.parent = 1 
union all 
    select concat(1000000 + a.id, '|', 
      1000000 + IFNULL(b.id,0), '|', 
      1000000 + IFNULL(c.id,0), '|') 
      ,concat(' - ', c.name) 
    from categories a 
    inner join category_relationships a1 on a1.parent_id = a.id 
    inner join categories b on b.id = a1.category_id 
    inner join category_relationships b1 on b1.parent_id = b.id 
    inner join categories c on c.id = b1.category_id 
    where a.parent = 1 
union all 
    select concat(1000000 + a.id, '|', 
      1000000 + IFNULL(b.id,0), '|', 
      1000000 + IFNULL(c.id,0), '|', 
      1000000 + IFNULL(d.id,0), '|') 
      ,concat('  - ', d.name) 
    from categories a 
    inner join category_relationships a1 on a1.parent_id = a.id 
    inner join categories b on b.id = a1.category_id 
    inner join category_relationships b1 on b1.parent_id = b.id 
    inner join categories c on c.id = b1.category_id 
    inner join category_relationships c1 on c1.parent_id = c.id 
    inner join categories d on d.id = c1.category_id 
    where a.parent = 1 
union all 
    select concat(1000000 + a.id, '|', 
      1000000 + IFNULL(b.id,0), '|', 
      1000000 + IFNULL(c.id,0), '|', 
      1000000 + IFNULL(d.id,0), '|', 
      1000000 + IFNULL(e.id,0)) 
      ,concat('  - ', e.name) 
    from categories a 
    inner join category_relationships a1 on a1.parent_id = a.id 
    inner join categories b on b.id = a1.category_id 
    inner join category_relationships b1 on b1.parent_id = b.id 
    inner join categories c on c.id = b1.category_id 
    inner join category_relationships c1 on c1.parent_id = c.id 
    inner join categories d on d.id = c1.category_id 
    inner join category_relationships d1 on d1.parent_id = d.id 
    inner join categories e on e.id = d1.category_id 
    order by SORT