2011-01-23 64 views
2

我有一個categories表看起來像這樣:如何將這兩個表連接在一起(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

分層查詢 - 哎喲...會很難。除非您事先知道層次結構的最大深度,否則除非DBMS支持「WITH RECURSIVE」子句(或非標準擴展,如「CONNECT BY」),否則無法編寫通用解決方案。 – 2011-01-23 22:26:34

回答

0

一個更好的/合適/健壯的答案很可能會創造一個MySQL程序這一點,但如果您的數據能夠適應這些限制,你可以用下面的:

  • 不超過5級(或根據需要擴大的圖案)
  • ID是不超過6個位數(或改變的concat表達式)

此查詢使用的毗連建立一個排序參考使得A的孩子來甲等後的名稱使用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