获取按模糊范围排序的每日值统计信息

时间:2011-11-17 17:09:55

标签: php mysql performance

好的以下任务;我有一个表有3列,ID,UserID和Time,这是一个DateTime-Type。现在我想得到以下统计数据:

我有5个范围:

  • 早上(早上6点 - 上午11点30分)
  • 中午(上午11点30分 - 下午2点)
  • 下午(下午2点至6点)
  • 晚上(下午6点至晚上10点)
  • 夜晚(晚上10点至早上6点)

例如,用户具有以下条目:

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日期函数解析它并获取时间本身,这真的没用,因为我可能会得到一些数量这些行每个userid。 日期本身必须存储在表中以用于其他任务。

2 个答案:

答案 0 :(得分: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

,它应该给你一个每个时间名称的时间范围内的所有事件的计数。

答案 1 :(得分:0)

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

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