2012-08-07 28 views
4

比方说,我的表看起来像这样:如何在MySql中使用单个查询按小时细分?

Sessions 
start_dts (datetime) 
end_dts (datetime) 

和数据如下:

start_dts    end_dts 
12/25/2011 01:55:00 12/25/2011 03:30:00 

我需要的查询结果是这样的:

Date   Hour MinutesOnline 
12/25/2011 0  0 
12/25/2011 1  5 
12/25/2011 2  60 
12/25/2011 3  30 
... (every hour of the date range being queried) 

这是甚至有可能使用单个查询?

+0

检查http://stackoverflow.com/questions/3366895/group-by-month-and-year-in-mysql – Matthew 2012-08-07 22:39:38

+1

@Matthew:无关 – zerkms 2012-08-07 22:40:00

+1

@Matthew:这里的主要问题是生成N行使用2日期作为输入。生成后,数据将准备好使用,无需进一步分组 – zerkms 2012-08-07 22:43:06

回答

1

这是一个非常好的开始。这将适用于任何日期/时间范围。但是,它有一个主要先决条件:您需要创建intervals表和dt_hr datetime字段,其​​中包含您正在扫描的所有时间间隔。

Ex: '2011-12-25 00:00:00', 
    '2011-12-25 01:00:00', 
    '2011-12-25 02:00:00', 
    '2011-12-25 03:00:00', 
      . . . 
    '2011-12-25 23:00:00' 

-

SELECT DATE_FORMAT(intervals.dt_hr,'%m/%d/%Y') AS Date, 
     EXTRACT(HOUR FROM intervals.dt_hr) AS Hour, 
     CASE 
      WHEN intervals.dt_hr > TIMESTAMPADD(HOUR,HOUR(s2.start_dts), DATE(s2.start_dts)) 
       AND intervals.dt_hr < TIMESTAMPADD(HOUR,HOUR(s2.end_dts), DATE(s2.end_dts)) 
      THEN 60 
      WHEN intervals.dt_hr = TIMESTAMPADD(HOUR,HOUR(s2.start_dts), DATE(s2.start_dts)) 
       AND intervals.dt_hr < TIMESTAMPADD(HOUR,HOUR(s2.end_dts), DATE(s2.end_dts)) 
      THEN 60 - EXTRACT(MINUTE FROM s2.start_dts) 
      WHEN intervals.dt_hr = TIMESTAMPADD(HOUR,HOUR(s2.end_dts), DATE(s2.end_dts)) 
       AND intervals.dt_hr > TIMESTAMPADD(HOUR,HOUR(s2.start_dts), DATE(s2.start_dts)) 
      THEN EXTRACT(MINUTE FROM s2.end_dts) 
      WHEN intervals.dt_hr = TIMESTAMPADD(HOUR,HOUR(s2.start_dts), DATE(s2.start_dts)) 
       AND intervals.dt_hr = TIMESTAMPADD(HOUR,HOUR(s2.end_dts), DATE(s2.end_dts)) 
      THEN EXTRACT(MINUTE FROM s2.end_dts) - EXTRACT(MINUTE FROM s2.start_dts) 
      ELSE 0 
     END AS MinutesOnLine 
FROM intervals 
LEFT JOIN sessions s2 
    ON intervals.dt_hr >= TIMESTAMPADD(HOUR,HOUR(s2.start_dts), DATE(s2.start_dts)) 
    AND intervals.dt_hr <= TIMESTAMPADD(HOUR,HOUR(s2.end_dts), DATE(s2.end_dts)) 

要生成intervals表,您可以创建与一个date_hour序列创建临时表的存储过程。请参阅Get a list of dates between two dates以获取此方法。

+0

这看起来很棒。明天我会跟进。 – 2012-08-08 04:36:24

+0

这工作出色。非常感谢。 – 2012-08-08 17:18:59

0

更多的是比回答更重要的评论。

不够好与MySQL做,但 的CTE拿出一套start_dts和end_dts 等你拿

startTime   endTime  
12/25/2011 01:00:00 12/25/2011 02:00:00 
12/25/2011 02:00:00 12/25/2011 03:00:00 
12/25/2011 03:00:00 12/25/2011 04:00:00 

之间的日期时间加盟回到会议在CT.EndTime <使用DateAdd( sessions.end_dts,INTERVAL 1小时)

然后小时(CTS.StartTime) - 小时(sessions.start_dts) 和高炮cte.endtime分钟的时间差的模量和start_dts

也许......

相关问题