2016-03-02 220 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