这是一个非常好的开始。这将适用于任何日期/时间范围。但是,它有一个主要先决条件:您需要创建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以获取此方法。
检查http://stackoverflow.com/questions/3366895/group-by-month-and-year-in-mysql – Matthew 2012-08-07 22:39:38
@Matthew:无关 – zerkms 2012-08-07 22:40:00
@Matthew:这里的主要问题是生成N行使用2日期作为输入。生成后,数据将准备好使用,无需进一步分组 – zerkms 2012-08-07 22:43:06