MySQL:按连续日和计数组分组

lin*_*ndy 8 mysql datetime gaps-and-islands

我有一个数据库表,用于保存每个用户在城市中的签到.我需要知道用户在一个城市中已经过了多少天,然后知道用户对一个城市进行了多少次访问(访问包括在城市中连续几天的访问).

所以,考虑我有下表(简化,只包含DATETIMEs - 相同的用户和城市):

      datetime
-------------------
2011-06-30 12:11:46
2011-07-01 13:16:34
2011-07-01 15:22:45
2011-07-01 22:35:00
2011-07-02 13:45:12
2011-08-01 00:11:45
2011-08-05 17:14:34
2011-08-05 18:11:46
2011-08-06 20:22:12
Run Code Online (Sandbox Code Playgroud)

天该用户已被这个城市的数目将是6(30.06,01.07,02.07,01.08,05.08,06.08).

我想过这样做 SELECT COUNT(id) FROM table GROUP BY DATE(datetime)

然后,该用户已经到这个城市做出的访问次数,查询应该返回3(30.06-02.07,01.08,05.08-06.08).

问题是我不知道如何构建此查询.

任何帮助将非常感谢!

Sim*_*mon 11

您可以通过查找前一天没有签到的签到来找到每次访问的第一天.

select count(distinct date(start_of_visit.datetime))
from checkin start_of_visit
left join checkin previous_day
    on start_of_visit.user = previous_day.user
    and start_of_visit.city = previous_day.city
    and date(start_of_visit.datetime) - interval 1 day = date(previous_day.datetime)
where previous_day.id is null
Run Code Online (Sandbox Code Playgroud)

此查询有几个重要部分.

首先,每个签到都加入前一天的任何签到.但由于它是外部联接,如果前一天没有签入,则联接的右侧将产生NULL结果.在WHERE后加入过滤发生,所以从左侧那里有从右侧一直没有只签入. LEFT OUTER JOIN/WHERE IS NULL找到没有的东西真的很方便.

然后它计算不同的签入日期,以确保如果用户在访问的第一天多次签入,则不会重复计算.(当我发现可能的错误时,我实际上在编辑时添加了那部分.)

编辑:我只是重新阅读您提出的第一个问题的查询.您的查询将获得给定日期的签到次数,而不是日期计数.我想你想要这样的东西:

select count(distinct date(datetime))
from checkin
where user='some user' and city='some city'
Run Code Online (Sandbox Code Playgroud)