mysql - 如何在 MySQL 中按日期对相关结果进行分组和排序

标签 mysql subquery grouping

我有一个有有效期的单位数据库。一些单元是顶级单元并附有子组件。子组件也有到期日。我正在尝试创建一个列表,列出按到期日期排序的顶级单元,并列出它们下面的所有相关子组件。

排序应该以两种不同的方式完成:

  1. 根据父项的到期日期列出顶级单元及其子组件的查询。
  2. 查询列出顶级单元及其下的相关子组件的第一个到期日期排序的子组件。

这是主表的例子:

    ITEM   | NAME             | UID | INSTALLED_TO_UID | EXPIRY  
    AAA    | Top_level_unit_1 | 1   |                  | 2018-03-06  
    BBB    | Sub_assy_1       | 75  | 1                | 2019-06-11  
    AAA    | Top_level_unit_2 | 2   |                  | 2018-08-12  
    CCC    | Sub_assy_2       | 26  | 1                | 2020-02-05  
    DDD    | Sub_assy_3       | 59  | 2                | 2019-11-11  
    EEE    | Sub_assy_4       | 41  | 2                | 2019-10-30  
    FFF    | Sub_assy_5       | 11  | 1                | 2018-04-10

我现在在嵌套查询中运行这些查询(foreach 循环内的第二个查询),但我确信有更好、更有效的方法来执行此操作。至少对于案例 1。

SELECT * 
  FROM master 
 WHERE ITEM = AAA 
 ORDER 
    BY EXPIRY ASC

每个结果的内部结果循环:

SELECT * 
  FROM master 
 WHERE INSTALLED_TO_UID = (UID from parent query)

结果应该是这样的:

    ITEM   | NAME             | UID | INSTALLED_TO_UID | EXPIRY  
    AAA    | Top_level_unit_1 | 1   |                  | 2018-03-06  
    BBB    | Sub_assy_1       | 75  | 1                | 2019-06-11  
    CCC    | Sub_assy_2       | 26  | 1                | 2020-02-05 
    FFF    | Sub_assy_5       | 11  | 1                | 2018-04-10
    AAA    | Top_level_unit_2 | 2   |                  | 2018-08-12   
    DDD    | Sub_assy_3       | 59  | 2                | 2019-11-11  
    EEE    | Sub_assy_4       | 41  | 2                | 2019-10-30 

对于案例 2,我还没有任何线索......

总结:我希望只有一个查询来对结果进行分组和排序,而不是依赖于结果循环中的另一个查询。其次,我想找出一个查询,通过首先使按父项分组的子项过期来对结果进行排序

最佳答案

您需要使用外部自联接来查找父记录(对于查询 1)或第一个子记录(对于查询 2)。然后,您可以使用 coalesce 来决定采用哪个值(来自联接表或主表)来设置顺序。

查询 1:

SELECT    record.* 
FROM      master record
LEFT JOIN master parent
       ON record.installed_to_uid = parent.uid
      AND parent.installed_to_uid is null
ORDER BY  COALESCE(parent.expiry, record.expiry),
          COALESCE(parent.uid, record.uid),
          COALESCE(record.installed_to_uid,-1),
          record.expiry

查询 2:

SELECT    record.* 
FROM      master record
LEFT JOIN (SELECT   installed_to_uid, MIN(expiry) expiry
           FROM     master
           WHERE    installed_to_uid IS NOT NULL
           GROUP BY installed_to_uid) first
       ON COALESCE(record.installed_to_uid, record.uid) = first.installed_to_uid
ORDER BY  COALESCE(first.expiry, record.expiry),
          COALESCE(first.installed_to_uid, record.uid),
          COALESCE(record.installed_to_uid,-1),
          record.expiry

查看它在 sqlfiddle 上运行

关于mysql - 如何在 MySQL 中按日期对相关结果进行分组和排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49189316/

相关文章:

mysql - 将选择标签上选定值的数据显示到另一个文本字段

mysql - mysql中8位数字转换为日期类型

mysql - 对每对求和 mysql 结果

r - 在 R 中计算分组 data.frame 期间是否有一种优雅的方法来显示进度条?

php - 将用户重定向到 php 中的同一页面问题

mysql - 如何检查嵌套查询返回的元组中的每个条目是否相同?

mysql - select 语句中的子选择返回 null

sql - 嵌入 select 语句的(相关)子查询中的别名范围

xml - 使用 XSLT 1.0 将 XML 元素根据某些条件按顺序分组到桶中

Mysql - 将两列相乘并减去差值