带有 MIN 和 MAX 的 GROUP BY - 属于解决方案的日期范围

Posted

技术标签:

【中文标题】带有 MIN 和 MAX 的 GROUP BY - 属于解决方案的日期范围【英文标题】:GROUP BY with MIN and MAX - Fall within date range of solution 【发布时间】:2016-08-21 07:01:52 【问题描述】:

我有以下数据表:

表1:

id  name    race_type        start_time              end_time
---     ----      ---------        ----------              --------
111 Phelps   Relay       2016-08-20 00:01:00           NULL
111 Phelps   Relay             NULL             2016-08-20 00:02:00
222 Phelps   Relay       2016-08-20 00:03:00           NULL
222 Phelps   Relay             NULL             2016-08-20 00:04:00
333 Lochte  Butterfly    2016-08-20 00:05:00           NULL
333 Lochte  Butterfly          NULL             2016-08-20 00:06:00
444 Lochte  Butterfly    2016-08-20 00:07:00           NULL
444 Lochte    Butterfly          NULL             2016-08-20 00:08:00

表2:

name      race_type        current_time       qualifies
----      ---------        ------------       ---------
Phelps      Relay       2016-08-20 00:03:30    
Lochte    Butterfly     2016-08-20 00:05:30

对于 Table2 中的两个事务,我需要确定这些事务的 CURRENT_TIME 是否在 Table1 记录的 START_TIME 和 END_TIME 范围内,关于每个唯一 ID 配对、名称和race_type。

我的想法是首先使用 GROUP BY 和 MIN 和 MAX 函数“合并”表 1 中的数据(id):

SELECT id,name,race_type, MIN(start_time) AS start_time, MAX(end_time) AS end_time
FROM Table1
GROUP BY id

这会给我以下结果:

+-----+--------+---------------+----------------------+---------------------+
| id  | name   |  race_type    |    start_time        |    end_time         |
+-----+--------+---------------+----------------------+---------------------|
| 111 | phelps |   relay       | 2016-08-20 00:01:00  | 2016-08-20 00:02:00 |
| 222 | phelps |   relay       | 2016-08-20 00:03:00  | 2016-08-20 00:04:00 |
| 333 | lochte |   Butterfly   | 2016-08-20 00:05:00  | 2016-08-20 00:06:00 |
| 444 | lochte |   Butterfly   | 2016-08-20 00:06:00  | 2016-08-20 00:08:00 |
+-----+--------+---------------+----------------------+---------------------+

基于这些结果,我可以更轻松地确定 phelps 或 lochte current_time 的接力或蝶泳(在表 2 中)是否在他们各自名称和 race_type 的开始或结束时间范围内。如果它确实属于这些范围之一,我会将 Table2 qualifies 参数设置为 true。

有人可以推荐一个可以完成这项任务的 mysql 查询吗?我猜我可以使用 GROUP BY 的某种组合来首先“合并”表 1 中的 id,而不是使用 exists?

【问题讨论】:

为什么将start_timeend_time 存储在不同的行中? 【参考方案1】:

您可以使用inner join 来获取当前时间在范围之间的所有结果:

SELECT * FROM (
SELECT id,name,race_type, MIN(start_time) AS start_time, MAX(end_time) AS end_time
FROM Table1
GROUP BY id
) AS results INNER JOIN table2 ON 
  results.name = Table2.name 
  AND results.type = Table2.type 
  AND Table2.current_time BETWEEN results.start_time AND results.end_time;

【讨论】:

基于此解决方案,在满足 INNER JOIN 结果后,如何另外将 table2.qualizes 参数设置为 true?例如。我正在寻找一个 UPDATE 和 SET qualifies = exists (...) somwehere?提前谢谢你。 为什么要设置它?我认为您不需要保存“计算”数据,如果实际数据发生变化,这些数据会发生变化。你有一个查询来获取这个数据,所以使用它,不需要特殊列【参考方案2】:

有两种方法可以用两个嵌套 GROUP BY 子查询来做你想做的事,但在你的情况下,我更喜欢这个:

update Table2 t2
set qualifies = exists(
    select 1
    from Table1 t1a
    join Table1 t1b using(name, race_type, id)
    where t1a.name      = t2.name
      and t1a.race_type = t2.race_type
      and t1a.start_time <= t2.current_time
      and t1b.end_time   >= t2.current_time
);

sqlfiddle

【讨论】:

以上是关于带有 MIN 和 MAX 的 GROUP BY - 属于解决方案的日期范围的主要内容,如果未能解决你的问题,请参考以下文章

min/max优化,count ,group by

不能在 Group by/Order by/Where/ON 子句中使用 Group 或 Aggregate 函数(min()、max()、sum()、count()、...等)

Django 查询模型 - GROUP BY、MIN、MAX

带有 SQL MIN() 和 GROUP BY 的额外字段

带有“Group by”、“max”和“join”的 SQL 请求?

带有 MAX() 的 GROUP BY 返回错误的行 ID