2013-08-06 58 views
1

MySQL數據庫包含城鎮內的國家,城鎮和地區,全部在「郵件」表中。我想按照粒度降序,使用和內連接的順序返回整個集合。我其實想要給用戶一個下拉列表,讓他們選擇一個城鎮內的國家或城鎮或地區。MySQL內部連接從同一個表中排序父,子和大孩子

的數據是這樣的:

 
mailshot_id mailshot_parent mailshot_name mailshot_level 
49    0    England   0 
56    0    Scotland  0 
140    49    London   1 
149    49    York   1 
191    56    Glasgow   1 
300    140    Wimbledon  2 
310    140    Westminster  2 
493    56    Edinburgh  1 

,我希望它這樣的輸出:

 
mailshot_id mailshot_parent mailshot_name mailshot_level 
49    0    England   0 
149    49    York   1 
140    49    London   1 
300    140    Wimbledon  2 
310    140    Westminster  2 
56    0    Scotland  0 
191    56    Glasgow   1 
493    56    Edinburgh  1 


我幾乎與此得到它:

 
SELECT 
    p.mailshot_id as p_id, 
    p.mailshot_name as p_name, 
    p.mailshot_level as p_level, 
    p.mailshot_parent as p_parent, 
    c.mailshot_id as c_id, 
    c.mailshot_parent as c_parent, 
    c.mailshot_level as c_level, 
    c.mailshot_name as c_name, 
    case 
     WHEN p.mailshot_parent = 0 THEN 
     p.mailshot_id 
     ELSE 
     p.mailshot_parent 
    END AS calcOrder 
FROM 
    mailshot p LEFT JOIN mailshot c 
    ON p.mailshot_id = c.mailshot_parent 
ORDER BY calcOrder , p_id " 

但它的沒有將孫子人記錄(第2級)與兒童記錄(第1級)分組在一起(我認爲「案例」部分必須是錯的,我需要t o根據級別,mailshot_id和parent_id之間有一些關係。但我想不出來。

有什麼建議嗎?提前致謝。

+0

我不看你怎麼想的順序,看上去一點y中有序我們希望的結果。你可以解釋嗎 ? –

+0

你可以給你的表的示例數據,或者如果你想要一個小提琴示例 –

+0

請*,因爲* echo_Me *建議,你可以創建一個http://sqlfiddle.com與您的表和數據樣本,以便做一些實驗。 –

回答

1

不幸的是,MySQL不支持層次查詢(沒有START WITH ... CONNECT BY或CTE等價物)。因爲你需要以這種艱難而醜陋的方式來做到這一點。

以下內容適用於您的3個關卡,但如果您在樹中需要更多深度,則會變得非常麻煩。這裏是Fiddle

SELECT C.MAILSHOT_ID 
     ,C.MAILSHOT_PARENT 
     ,C.MAILSHOT_NAME 
     ,C.MAILSHOT_LEVEL 
     ,CASE WHEN C.MAILSHOT_LEVEL = 0 
       THEN CAST(C.MAILSHOT_ID AS CHAR(4)) 
       WHEN C.MAILSHOT_LEVEL = 1 
       THEN CONCAT(CAST(C.MAILSHOT_PARENT AS CHAR(4)),"..",CAST(C.MAILSHOT_ID AS CHAR(4))) 
       ELSE CONCAT(CAST(P.MAILSHOT_PARENT AS CHAR(4)),"..",CAST(C.MAILSHOT_PARENT AS CHAR(4)),"..",CAST(C.MAILSHOT_ID AS CHAR(4))) 
     END AS SORT_ORDER  
FROM MAILSHOT C 
LEFT OUTER JOIN 
     MAILSHOT P 
ON  P.MAILSHOT_ID = C.MAILSHOT_PARENT  
ORDER BY CASE WHEN C.MAILSHOT_LEVEL = 0 
       THEN CAST(C.MAILSHOT_ID AS CHAR(4)) 
       WHEN C.MAILSHOT_LEVEL = 1 
       THEN CONCAT(CAST(C.MAILSHOT_PARENT AS CHAR(4)),"..",CAST(C.MAILSHOT_ID AS CHAR(4))) 
       ELSE CONCAT(CAST(P.MAILSHOT_PARENT AS CHAR(4)),"..",CAST(C.MAILSHOT_PARENT AS CHAR(4)),"..",CAST(C.MAILSHOT_ID AS CHAR(4))) 
     END 
+0

這是天才!非常感謝這個Declan。我很欣賞這一點。這正是我想要的。感謝其他人對包含SQL數據樣本的建議,我將在未來做到這一點,以便於實驗。 –

1

這是一個分級表,這是更容易在oracle中查詢一個典型的例子,但是這不是重點。 @Declan_K給你一個很好的答案來實現你想要的。如果你正在尋找的是給你一個稍微不同的仍然很好地組織輸出的選擇,你可以試試這個方法:

SELECT m1.mailshot_name AS lev1n ,   
     m1.mailshot_id AS lev1, 
     m1.mailshot_parent AS lev1p, 
     m2.mailshot_name AS lev2n, 
     m2.mailshot_id AS lev2, 
     m2.mailshot_parent AS lev2p, 
     m3.mailshot_name lev3n, 
     m3.mailshot_id lev3, 
     m3.mailshot_parent AS lev3p 
FROM mailshot m1 
LEFT JOIN mailshot m2 ON m2.mailshot_parent = m1.mailshot_id 
LEFT JOIN mailshot m3 ON m3.mailshot_parent = m2.mailshot_id 
WHERE m1.mailshot_parent = 0; 

給出輸出:

+----------+------+-------+-----------+------+-------+-------------+------+-------+ 
| lev1n | lev1 | lev1p | lev2n  | lev2 | lev2p | lev3n  | lev3 | lev3p | 
+----------+------+-------+-----------+------+-------+-------------+------+-------+ 
| England | 49 |  0 | London | 140 | 49 | Wimbledon | 300 | 140 | 
| England | 49 |  0 | London | 140 | 49 | Westminster | 310 | 140 | 
| England | 49 |  0 | York  | 149 | 49 | NULL  | NULL | NULL | 
| Scotland | 56 |  0 | Glasgow | 191 | 56 | NULL  | NULL | NULL | 
| Scotland | 56 |  0 | Edinburgh | 493 | 56 | NULL  | NULL | NULL | 
+----------+------+-------+-----------+------+-------+-------------+------+-------+ 

關於如何處理分層良好摘要在MySQL的數據可以在這裏找到:
http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
http://explainextended.com/2009/03/17/hierarchical-queries-in-mysql/

+1

這是聰明的東西。我相信我可以在未來的項目中使用它或類似的東西。感謝您的貢獻和鏈接。 StackOverflow社區真是太棒了! –