选择具有计数条件的日期

时间:2015-02-07 17:34:31

标签: mysql time-series aggregate-functions

我的表userlogin_time

我想选择一个月内登录超过10次的所有用户。

我试过这样的事情:

SELECT login_time, count(id) as loginCount FROM user 

WHERE login_time between DATE_SUB(login_time INTERVAL 1 month) AND login_time

GROUP BY id, MONTH(login_time) HAVING loginCount > 10;

我不确定我在日期之间的选择。 如何选择月份间隔,避免双重记录。 例如,如果我有login_time的这个值:

1. '2015-02-01 14:05:19'
2. '2015-01-21 14:05:19'
3. '2015-01-11 14:05:19'

3和2都在1的月份范围内。 那么我会得到这些值的双重记录吗?

1 个答案:

答案 0 :(得分:1)

要查找在当月结束时登录十次以上的用户,请执行此操作。

SELECT COUNT(*) times_logged_in,
       userid
  FROM user
 WHERE login_time >= NOW() - INTERVAL 1 MONTH
 GROUP BY user_id
HAVING COUNT(*)> 10

要查找在表格中任何日历月内登录十次以上的用户,请执行此操作。

SELECT COUNT(*) times_logged_in,
       DATE(DATE_FORMAT(login_time, '%Y-%m-01')) month_beginning,
       userid
  FROM user
 GROUP BY user_id, DATE(DATE_FORMAT(login_time, '%Y-%m-01'))
HAVING COUNT(*)> 10

这里的技巧是表达式DATE(DATE_FORMAT(login_time, '%Y-%m-01')),它将任何时间戳转换为发生它的月份的第一天。

您的问题提到了这个WHERE条件:

WHERE login_time between DATE_SUB(login_time INTERVAL 1 month) AND login_time

这并没有做任何有趣的事情,因为它总是回归真实。每个给定的login_time总是落在您指定的区间内。

修改:如果需要,您可以GROUP BY MONTH(dt)。但我自动显示它的方式会自动占多年和几个月,所以在我看来,这对于准确报道来说要好得多。

另一个修改:此公式为任何给定的日期或时间戳项生成前一个星期日。

FROM_DAYS(TO_DAYS(login_time) -MOD(TO_DAYS(login_time) -1, 7))

如果星期一是您所在司法辖区的一周中的第一天,请将-1更改为-2。通过此功能进行分组优于执行GROUP BY WEEK(login_time),因为WEEK()在日历年的开头和结尾处做了奇怪的事情。

这里有更详细的内容:http://www.plumislandmedia.net/mysql/sql-reporting-time-intervals/