2013-05-29 80 views
2

我有一個MySQL表如下領域:MySQL的單親家庭子女一個查詢選擇

id   name    parent 
1    Fruit    0 
2    Meat    0 
3    Orange   1 
4    Beef    2 

其中父字段指上級ID。例如Fruit id是1,橙色是其中一個水果,所以父級是1.

但是我想要做一個高效的MySQL查詢來獲取格式爲parent-> children-> parent-> children的所有記錄格式。我怎樣才能做到這一點?

查詢結果記錄應該是這樣的:

id   name    parent 
1    Fruit    0 
3    Orange   1 
2    Meat    0 
4    Beef    2 

回答

5

你需要一個遞歸加入哪個MySQL不支持你只想到你能做的就是確定深度的最高水平(我的情況下,它1,因爲你必須對 - > c)和與此可以判斷的聯接所需要的數目:深度的最大電平=數自連接

SELECT 
    p.id as parent_id, 
    p.name as parent_id, 
    c1.id as child_id, 
    c1.name as child_name 
FROM 
    my_table p 
LEFT JOIN my_table c1 
    ON c1.parent = p.id 
WHERE 
    p.parent=0 

例如,如果深度的你最大電平是3你需要3自我連接:

SELECT 
    p.id as parent_id, 
    p.name as parent_id, 
    c1.id as child_id_1, 
    c1.name as child_name_1, 
    c2.id as child_id_2, 
    c2.name as child_name_2, 
    c3.id as child_id_3, 
    c3.name as child_name_3 
FROM 
    my_table p 
LEFT JOIN my_table c1 
    ON c1.parent = p.id 
LEFT JOIN my_table c2 
    ON c2.parent = c1.id 
LEFT JOIN my_table c3 
    ON c3.parent = c2.id 
WHERE 
    p.parent=0 
+0

謝謝,你知道這個查詢的效率? – onegun

+0

由於它的連接速度應該很快,特別是如果你有一個「父」的索引 – Stephan

+1

子句的WHERE部分不需要表別名嗎?我不認爲: parent = 0 將工作。 – omarjebari

1

這個怎麼樣?

select * from foods 
order by (case parent when 0 then id*1000 else parent*1000+id end), id 

這不是很漂亮,因爲如果你有超過1000噸的食物具有相同父它不會工作,但如果你知道這個限制,它應該做的伎倆。

-1

您可以使用下面的查詢與UNION

SELECT ID, NAME, PARENT 
FROM MY_TABLE AS A, 
    MY_TABLE AS B 
WHERE A.PARENT != 0 AND 
     A.PARENT = B.ID 
UNION 
SELECT ID, NAME, PARENT 
FROM MY_TABLE 
WHERE PARENT == 0 
0

這裏是另一種選擇,讓你正在尋找的結果。你可以通過父母的id一起將父母和孩子分組在一起,然後指出哪個記錄​​是父母(isparent)......就像這樣:(這個例子假設父母記錄有一個NULL值,而不是0 ..但它可以工作得0)

SELECT 
    IFNULL(parent,id) AS parentid, 
    IF(parent IS NULL,1,0) AS isparent, 
    name 
FROM my_table 
ORDER BY 
    parentid ASC, <- groups/orders all parentid's together 
    isparent DESC, <- orders the parent first 
    id DESC <- orders children by their id next 

其餘的應該很容易弄清楚,你的分組輸出等