2016-03-02 185 views
7

我想在波紋管表上寫一個SQL查詢。SQL查詢父親的孩子關係

╔════╦══════════╦═══════╗======╗======╗ 
║ ID ║ NAME ║ CLASS ║PARENT║ DOB ║ 
╠════╬══════════╬═══════╣======║======║ 
║ 1 ║ DAVID ║ SPIN ║  ║1  ║ 
║ 2 ║ AROON ║ BIKE ║ 1 ║1  ║ 
║ 3 ║ LEO ║ YOGA ║  ║2  ║ 
║ 4 ║ LIN ║ CYC ║ 1 ║2  ║ 
║ 5 ║ STEFA ║ YOGA ║  ║3  ║ 
║ 6 ║ GLORIA ║ RUNN ║ 1 ║3  ║ 
╚════╩══════════╩═══════╝======╝======╝ 

而且,在此表輸出應該像下面

╔════╦════════╦═══════╗======╗======╗ 
║ ID ║ NAME ║ CLASS ║PARENT║ DOB ║ 
╠════╬════════╬═══════╣======║======║ 
║ 1 ║ DAVID ║ SPIN ║  ║1  ║ 
║ 2 ║ AROON ║ BIKE ║ 1 ║1  ║ 
║ 4 ║ LIN ║ CYC ║ 1 ║2  ║ 
║ 6 ║ GLORIA║ RUNN ║ 1 ║3  ║ 
║ 3 ║ LEO ║ YOGA ║  ║2  ║ 
║ 5 ║ STEFAN║ YOGA ║  ║3  ║ 
╚════╩════════╩═══════╝======╝======╝ 

So this is the explanation of the output 
First parent David as his DOB is 1, 
--David three childrens sorted based on DOB 
Then LEO as his DOB is 2 
-- Leo do not have children[if he did, would be here as sorted on DOB] 
Then Stefan as his DOB is 3 
-- Stefan do not have children [if he did, would be here as sorted on DOB] 

所以我試過嗎?

SELECT * FROM user group by ID, PARENT ; 

上面的SQL,在父母的子女組聲明回報的項目,但不是不維護任何順序,當我添加ORDER BYSQL不好像履行GROUP BY了。

然後我試圖加入並以兩個完整的不同表格結束,其中一個包含所有父母,另一個包含所有孩子。 UNION ALL在這兩個查詢返回預期的數據集,但不是按預期的順序。

有什麼想法?

UPDATE

Output should be 
Pick entry [based on min time ]. 
--use that id and find all of its children and placed them in sorted order 
repeat for every row in the table 

注:

--parents are sorted based on DOB 
--child's are also sorted based on DOB 
--DOB are valid timestamp 
--PARENT, ID field both are UUID and define as CHAR, PARENT reference to ID 

SQL Fiddle

Similar on SO

更新1

查詢波紋管

WITH RECURSIVE 
top AS (
    SELECT * FROM (SELECT * FROM user WHERE PARENT is null ORDER BY dob LIMIT 1) 
    UNION 
    SELECT user.NAME, user.PARENT, user.ID, user.CLASS, user.DOB FROM user, top WHERE user.PARENT=top.ID 
    ORDER BY user.dob 
) SELECT * FROM top; 

返回下面的輸出:

╔════╦════════╦═══════╗======╗======╗ 
║ ID ║ NAME ║ CLASS ║PARENT║ DOB ║ 
╠════╬════════╬═══════╣======║======║ 
║ 1 ║ DAVID ║ SPIN ║  ║1  ║ 
║ 2 ║ AROON ║ BIKE ║ 1 ║1  ║ 
║ 4 ║ LIN ║ CYC ║ 1 ║2  ║ 
║ 5 ║ GLORIA║ RUNN ║ 1 ║3  ║ 
╚════╩════════╩═══════╝======╝======╝ 

輸出是良好的第一個親本。但是,仍然無法弄清楚,我如何通過排序順序遍歷其餘的父母和他們的孩子。

+0

輸出看起來與輸入相同。這裏發生了什麼? –

+0

不只是檢查出來放在不同的地方。 – minhaz

+0

我看到的唯一區別是排序。我也不會爲使用'GROUP BY'使用'SELECT *'而瘋狂。 –

回答

5

查詢

SELECT u1.* 
FROM `user` u1 
LEFT JOIN `user` u2 
ON u1.PARENT = u2.ID 
ORDER BY CASE WHEN u1.PARENT IS NULL THEN u1.DOB ELSE u2.DOB END 
     || CASE WHEN u1.PARENT IS NULL THEN '' ELSE u1.DOB END; 

說明

  1. 別名u1擁有所有用戶的詳細信息
  2. 別名u2具有適用母公司的細節在哪裏。 (使用了A LEFT JOIN,因此如果u1用戶沒有父級,這些詳細信息將全部爲null)。
  3. 如果用戶沒有父級,則使用其自身的DOB進行排序。
  4. 如果用戶有父級,則取用戶父級的DOB並連接(追加)用戶(子級)的DOB。

結果用於ORDER BY

構建的值(其實際上不需要在SELECT)看起來最右邊的列的位置:

╔════╦════════╦═══════╗======╗======╦════════╗ 
║ ID ║ NAME ║ CLASS ║PARENT║ DOB ║ORDER BY║ 
╠════╬════════╬═══════╣======║======╬════════║ 
║ 1 ║ DAVID ║ SPIN ║  ║1  ║ 1  ║ 
║ 2 ║ AROON ║ BIKE ║ 1 ║1  ║ 11  ║ 
║ 4 ║ LIN ║ CYC ║ 1 ║2  ║ 12  ║ 
║ 6 ║ GLORIA║ RUNN ║ 1 ║3  ║ 13  ║ 
║ 3 ║ LEO ║ YOGA ║  ║2  ║ 2  ║ 
║ 5 ║ STEFAN║ YOGA ║  ║3  ║ 3  ║ 
╚════╩════════╩═══════╝======╝======╩════════╝ 

演示

SQL Fiddle Demo

2

這裏是一個ORDER BY我相信這是正確的邏輯:

ORDER BY COALESCE(PARENT, DOB) ASC, 
    CASE WHEN PARENT IS NULL THEN 0 ELSE DOB END 

這個回答假設當然,你實際上可以在查詢中使用PARENTDOB列。通常不應該是SELECT列,它們不是GROUP BY子句中的集合或指定的列。

如果PARENTDOB被定義爲varchar那麼你可以嘗試一下強制轉換爲數值類型:

CAST(PARENT as integer) 

你可能想使這些UUID的是數字型改變你的表設計。

+0

你認爲,它會保持基於DOB的嚴格排序嗎? – minhaz

+0

是的,我相信這會起作用。請嘗試一下,然後回頭看看你所看到的。 –

+0

是的,如果'parent'和'id'是整數,這是完美的。但在這種情況下,兩者都是UUID並且定義爲char。 prent字段基本上是指父代的id。我還添加了SQL小提琴的鏈接 – minhaz