【问题标题】:SQL query for parent children relation父子关系的SQL查询
【发布时间】:2016-03-02 01:04:19
【问题描述】:

我正在尝试在下表中编写一个 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 在这两个查询上返回了预期的数据集,但不是按预期的顺序。

有什么想法吗?

更新

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

输出对第一个父母有好处。但是,仍然无法弄清楚,我怎样才能按排序顺序遍历其余的父母和他们的孩子。

【问题讨论】:

  • 输出看起来与输入相同。这是怎么回事?
  • 不只是重新检查的 put 与 put 不同。
  • 我看到的唯一区别是排序。我也不喜欢使用SELECT *GROUP BY
  • 是的,你是对的,这里有两种不同的顺序。没有孩子的条目被排序,孩子也被排序,因为它们被放置在自己的父母之后。
  • 我真的不明白你想在输出中显示什么。此外,在 id 列上进行分组没有任何意义 - 大概所有 id 都是唯一的,因此没有什么可分组的。

标签: android sqlite


【解决方案1】:

查询

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,因此如果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 为数字类型。

    【讨论】:

    • 你认为,它会保持基于 DOB 的严格排序吗?
    • 是的,我相信这会奏效。请尝试一下,然后带着你看到的回到这里。
    • 是的,如果 'parent' 和 'id' 是整数,这将非常有效。但是,在这种情况下,两者都是 UUID 并定义为 char。 prent 字段基本上是指父级的 id。我还添加了指向 SQL 小提琴的链接
    • 尝试使用CAST() 将类型从字符更改为数字。正如您的 SQL Fiddle 所示,之后我的 ORDER BY 子句将正常工作。
    • 强制转换不是一种选择,因为所有 ID 都是标准 UUID。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-27
    相关资源
    最近更新 更多