2011-11-17 49 views
0

确定以下任务;我有一个表有3列,ID,用户ID和时间,这是一个DateTime类型。现在,我希望得到如下统计:获取以模糊范围排序的每日价值统计信息

我有5个量程:

  • 上午(早上6点 - 上午11:30)
  • 中午(11:30 - 14:00)
  • 下午(14:00 - 下午6:00)
  • 晚间(下午6点 - 下午10点)
  • 晚(下午10点 - 上午06点)

用户具有,作为例子,下面的条目:

ID UserID Time 
46 1  2011-11-17 17:51:24 
47 1  2011-11-17 11:41:41 
48 1  2011-11-17 07:31:20 
49 1  2011-11-17 21:41:55 
50 1  2011-11-17 21:58:28 
99 1  2011-11-18 10:12:18 

我的目标是,让下面的数组:

Array (
['today'] => Array (
    ['morning'] => 1, 
    ['noon'] => 1, 
    ['afternoon'] => 1, 
    ['evening'] => 2, 
    ['night'] => 0 
) 
['all'] => Array (
    ['morning'] => 2, 
    ['noon'] => 1, 
    ['afternoon'] => 1, 
    ['evening'] => 2, 
    ['night'] => 0 
) 
['avg'] => Array (
    ['morning'] => 1.5, 
    ['noon'] => 0.5, 
    ['afternoon'] => 0.5, 
    ['evening'] => 1, 
    ['night'] => 0 
) 
) 

好,它的工作原理,如果我真的会在结果集中的用户的所有值的迭代,但我敢打赌,通过MySQL及其日期函数有一种更简单的方法。如果我尝试参加所有参赛作品,只想获得时间而不是日期,我也会遇到问题。我需要首先通过php日期函数解析它,并获取时间本身,这实际上并没有用,因为我可能会为每个用户标识搜索几千行这些行。 日期本身必须存储在表中以执行其他任务。

回答

2

我建议把这些日期范围到一个表,在时间字段

timenames: 
id name  start  end 
1 Morning 00:06:00 11:29:59 
2 Noon  11:30:00 13:59:59 
etc... 

然后,你可以做

SELECT timenames.name, timenames.start, timenames.end, COUNT(users.id) 
FROM timenames 
LEFT JOIN users ON (TIME(users.`Time`) BETWEEN timenames.start AND timenames.end) 
GROUP BY timenames.id 

这应该给你的每个时间内的所有事件的计数名字的时间范围。

+0

这很好用!非常感谢你! –

0

MySQL有一个CASE构造,它类似于PHP中的构造。你可以用它来根据时间值为每行赋予一个标识符,然后使用普通的GROUP函数等来返回你想要的数据。

如果系统具有非常高的SELECT到INSERT/UPDATE比率,那么您可能需要考虑使用denormalising数据来提高性能。

+0

我也考虑过将时间存储为从0到86400秒的日期和独立的日期,但在其他一些情况下,这也会降低性能。所以不幸的是没有选择。我将看看CASE结构。 –