如何选择给定日期的最小开始和最大结束之间的小时差?

时间:2014-03-11 13:02:01

标签: php mysql sql

我遇到了一个简单的问题,但是我很难设法制定正确的SQL查询来完成这项工作。我有一张有多个日期的桌子。每个日期都有多次。时间是由用户手动添加的开始 - 结束增量。

+----+------------------+------------------+
| id | start            | end              |
+----+------------------+------------------+
|  6 | 2014/03/03 08:30 | 2014/03/03 09:00 |
|  7 | 2014/03/03 09:00 | 2014/03/03 11:15 |
|  8 | 2014/03/03 11:15 | 2014/03/03 11:45 |
|  9 | 2014/03/03 11:45 | 2014/03/03 12:45 |
| 10 | 2014/03/03 12:45 | 2014/03/03 13:15 |
| 11 | 2014/03/04 08:45 | 2014/03/04 09:00 |
| 12 | 2014/03/04 09:00 | 2014/03/04 13:00 |
| 13 | 2014/03/04 13:00 | 2014/03/04 13:30 |
| 14 | 2014/03/05 09:00 | 2014/03/05 09:30 |
| 15 | 2014/03/05 09:30 | 2014/03/05 12:30 |
| 16 | 2014/03/05 12:45 | 2014/03/05 12:45 |
| 19 | 2014/03/06 08:45 | 2014/03/06 09:00 |
| 20 | 2014/03/06 09:15 | 2014/03/06 10:00 |

我正在尝试计算每个日期的最早开始时间和最晚结束时间之间的小时数差异。

目前我只在我的行上使用简单的unix_timestamp转换,但是,它只计算找到的第一行之间的差异,而不是给定日期的所有行的差异。

select
    unix_timestamp(min(start)) - unix_timestamp(max(end)) / 60.0 / 60.0 as hours_difference,
    min(start) as started,
    min(end) as ended              
from
    athlete_log
group by
    day(start)

问题(如上所述)是它只抓取给定日期的第一行,例如:

| 6 | 2014/03/03 08:30 | 2014/03/03 09:00 |

但是我需要最早的开始时间和最近的开始时间:

|  6 | 2014/03/03 08:30 | 2014/03/03 09:00 |
|  7 | 2014/03/03 09:00 | 2014/03/03 11:15 |
|  8 | 2014/03/03 11:15 | 2014/03/03 11:45 |
|  9 | 2014/03/03 11:45 | 2014/03/03 12:45 |
| 10 | 2014/03/03 12:45 | 2014/03/03 13:15 |

哪个应该产生:

2014/03/03 8:30 - start
2014/03/03 13:15 - end
5.45 - hours_difference

但当然只会选择

2014/03/03 8:30 - start
2014/03/03 9:00 - end
.30 - hours_difference

如何修改查询以选择给定日期的最小开始和最大结束?

3 个答案:

答案 0 :(得分:1)

您已对DAY()进行分组,这可能不正确。您只显示2014年3月的数据,但如果您的数据库实际上有的数据来自更多月/年,那么您将分组到2014/03 / 03,2014 / 02 / 03,2013 / 02/03/03等等。(不同的年/月,同一天)

您应该GROUP BY DATE(start),因此您可以对完整的YYYY-MM-DD日期值进行分组。

答案 1 :(得分:1)

这就是你想要的东西

更新:第一次错过了小组,试试这个

SELECT A.starter - A.ender, dates
FROM(
SELECT Min([start]) as starter
      ,Max([end]) as ender
      ,CONVERT (DATE, [start]) as dates
  FROM athlete_log
  Group By CONVERT (DATE, [start]) ) as A

如果您只想要值,则不需要选择顶部。内部选择抓取顶级做算术的值。如果您有任何疑问,请随时提出。

答案 2 :(得分:1)

可能就像这样

SELECT started, ended, (unix_timestamp(ended) - unix_timestamp(started)) / (60.0 * 60.0)  as hours_difference
FROM
(
    SELECT DATE(start) AS start_date,
        MIN(start) as started,
        MAX(end) as ended              
    FROM athlete_log
    GROUP BY start_date
) Sub1;

可以缩短到这个

SELECT DATE(start) AS start_date,
    MIN(start) as started,
    MAX(end) as ended,
    (unix_timestamp(MAX(end)) - unix_timestamp(MIN(start))) / (60.0 * 60.0) as hours_difference
FROM athlete_log
GROUP BY start_date;

SQL小提琴: -

http://www.sqlfiddle.com/#!2/43757/7