父子关系的SQL查询

时间:2016-03-02 01:04:20

标签: android sqlite

我正在尝试在波纹管表上编写一个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 BY时,SQL似乎不再支持GROUP BY。

然后我尝试加入并以两个完整的不同表结束,其中一个包含所有父项,另一个包含所有子项。这两个查询的UNION ALL返回了预期的数据集但未按预期顺序返回。

有什么想法?

更新

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     ║
╚════╩════════╩═══════╝======╝======╝

输出对第一位父母有好处。但是,仍然无法弄清楚,我怎么能按照排序的顺序迭代其余的父母和他们的孩子。

2 个答案:

答案 0 :(得分: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包含适用的父级详情。 (使用了LEFT JOIN,因此如果null用户没有父母,这些详细信息都将为u1。)
  3. 如果用户没有父母,请自行使用其DOB进行订购。
  4. 如果用户有父母,则取用户父母的DOB并连接(追加)用户(孩子)的DOB。
  5. <强>结果

    用于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

答案 1 :(得分: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是数字类型。