› MySQL 5.5 Community Server
› MySQL 5.6 Community Server
› Percona Configuration Wizard
› XtraBackup 搭建主从复制
Great Sites on MySQL
› Percona
› MySQL Performance Blog
› Severalnines
推荐管理工具
› Sequel Pro
› phpMyAdmin
推荐书目
› MySQL Cookbook
MySQL 相关项目
› MariaDB
› Drizzle
参考文档
› http://mysql-python.sourceforge.net/MySQLdb.html
NowTime
V2EX  ›  MySQL

MySQL 如何查询每一天的用户注册数量(近 7 日、15 日、30 日...)?

  •  
  •   NowTime · Apr 25, 2019 · 11411 views
    This topic created in 2752 days ago, the information mentioned may be changed or developed.

    SegmentFault: https://segmentfault.com/q/1010000018986285

    已经使用 Google 搜索过,没找到合适的答案(有些看不懂)

    有以下表:

    表字段: id 是用户唯一 id reg_time 是用户注册时间戳

    mysql> SELECT id,reg_time FROM `apps_user` ;
    +----+------------+
    | id | reg_time   |
    +----+------------+
    |  1 | 1524322845 |
    |  2 | 1524322945 |
    |  3 | 1524323277 |
    |  4 | 1524325325 |
    |  5 | 1524325451 |
    |  6 | 1524325517 |
    |  7 | 1524340390 |
    |  8 | 1524346779 |
    |  9 | 1524346875 |
    | 10 | 1524419896 |
    | 11 | 1524456557 |
    | 12 | 1524456564 |
    | 13 | 1524456663 |
    | 14 | 1524499581 |
    | 15 | 1524504637 |
    | 16 | 1524504718 |
    | 17 | 1524523875 |
    | 18 | 1524528715 |
    | 19 | 1524542755 |
    | 20 | 1524543480 |
    +----+------------+
    20 rows in set (0.00 sec)
    

    我想要获取近 7 天、自定义时间范围内中的 每一天用户注册量

    例如,我想要近 7 天中每一天的用户注册量,预想返回结果如下(这里的预想返回结果与开头表的数据无关联):

    +-------------+-------+
    |    date     | total |
    +-------------+-------+
    |  2019-04-19 |   3   |
    |  2019-04-20 |   0   |
    |  2019-04-21 |   0   |
    |  2019-04-22 |   8   |
    |  2019-04-23 |   0   |
    |  2019-04-24 |   9   |
    |  2019-04-25 |   2   |
    

    请大神解答,先谢谢了!

    Supplement 1  ·  Apr 26, 2019

    在这里统一回复下,我应该算是个业余开发(或者根本不算吧=.=),凭自己兴趣写了个小项目,写后台时,需要用折线图展现出近 7 日等某个时间范围内的每天的注册人数。

    最开始想到是一天天去 count,但我个人觉得对性能有一些影响; 然后想着有没有办法直接查询一次就能获取到指定时间范围内每一天的用户注册量,接着去 Google 搜,翻了几页,没有找到合适的答案,然后就在 SegmentFault 上提问,然后又发到 v2ex

    总结,我还是太年轻,也向各位大佬学习了🙏

    36 replies  •  2019-07-11 15:53:01 +08:00
    lihongjie0209
    lihongjie0209
    Apr 25, 2019
    1
    你应该不是开发吧
    momo1999
    momo1999
    Apr 25, 2019
    2
    先搞个任务,把每一天的注册人数写一个表里面,然后 7 天什么的都是小意思。
    glacer
    glacer
    Apr 25, 2019
    3
    时间戳转成 date,然后 group by
    kisshere
    kisshere
    Apr 25, 2019 via Android
    4
    保持队形,你应该不是开发吧
    luozic
    luozic
    Apr 25, 2019❤️8
    5
    mysql 按时间段统计(年,季度,月,天,时)
    按年汇总,统计:

    select sum(mymoney) as totalmoney, count(*) as sheets from mytable group by date_format(col, '%Y');

    按月汇总,统计:

    select sum(mymoney) as totalmoney, count(*) as sheets from mytable group by date_format(col, '%Y-%m');

    按季度汇总,统计:

    select sum(mymoney) as totalmoney,count(*) as sheets from mytable group by concat(date_format(col, '%Y'),FLOOR((date_format(col, '%m')+2)/3));

    select sum(mymoney) as totalmoney,count(*) as sheets from mytable group by concat(date_format(col, '%Y'),FLOOR((date_format(col, '%m')+2)/3));

    按小时:

    select sum(mymoney) as totalmoney,count(*) as sheets from mytable group by date_format(col, '%Y-%m-%d %H ');

    查询 本年度的数据:

    SELECT * FROM mytable WHERE year(FROM_UNIXTIME(my_time)) = year(curdate())

    查询数据附带季度数:

    SELECT id, quarter(FROM_UNIXTIME(my_time)) FROM mytable;

    查询 本季度的数据:

    SELECT * FROM mytable WHERE quarter(FROM_UNIXTIME(my_time)) = quarter(curdate());

    本月统计:

    select * from mytable where month(my_time1) = month(curdate()) and year(my_time2) = year(curdate())

    本周统计:

    select * from mytable where month(my_time1) = month(curdate()) and week(my_time2) = week(curdate())

    N 天内记录:

    WHERE TO_DAYS(NOW())-TO_DAYS(时间字段)<=N

    本篇文章来源于 Linux 公社网站(www.linuxidc.com) 原文链接: http://www.linuxidc.com/Linux/2012-11/74145.htm
    dovme
    dovme
    Apr 25, 2019
    6
    用 date_format(date, format) 将注册时间转化为 2019-04-19 这样的格式,然后 groupby
    CallMeReznov
    CallMeReznov
    Apr 25, 2019
    7
    想当年我运维入职,老板让我上线上 SQLSERVER 服务器查东西.手抖的一批...
    不过还好我知道有个 count()
    cjlmwcy
    cjlmwcy
    Apr 25, 2019
    8
    你应该不是开发吧
    goodbye1014ac
    goodbye1014ac
    Apr 25, 2019
    9
    你应该不是开发吧
    misaka19000
    misaka19000
    Apr 25, 2019
    10
    在写数据的时候把 年、年-月、年-月-日 这种数据结构写到数据库中,之后可以直接使用 group 来进行搜索
    kifile
    kifile
    Apr 25, 2019
    11
    你应该不是开发吧
    cjlmwcy
    cjlmwcy
    Apr 25, 2019❤️1
    12
    SELECT
    COUNT(u.id) AS total,
    DATE_FORMAT(
    FROM_UNIXTIME(u.reg_time),
    '%Y-%m-%d'
    ) AS date
    FROM
    apps_user AS u
    WHERE
    FROM_UNIXTIME(u.reg_time) >= DATE_ADD(NOW(), INTERVAL - 7 DAY)
    GROUP BY
    date
    richChou
    richChou
    Apr 25, 2019
    13
    甚至可能都不是资深产品经理
    thisisgpy
    thisisgpy
    Apr 25, 2019
    14
    你这问题吓得我一度怀疑自己到底会不会做开发
    liuzhaowei55
    liuzhaowei55
    Apr 25, 2019❤️2
    15
    楼上那些讽刺楼主的都是臭傻逼,有一个算一个。
    二楼的做法是一个解决方案,主要问题就是如果某一天没有用户注册,直接用 SQL 是无法查询出来这天的统计数据的,所以需要结合逻辑解决问题,不能直接通过 SQL 获得最终结果。
    liuzhaowei55
    liuzhaowei55
    Apr 25, 2019
    17
    @junan0708 首先表示感谢,其次就是希望下次不会遇到有人问统计半年内结果怎么办的问题了。
    F281M6Dh8DXpD1g2
    F281M6Dh8DXpD1g2
    Apr 25, 2019
    18
    @liuzhaowei55 一个比较简单的做法是先做个日期表,然后用注册表左关联之后就可以补零了
    另外讽刺楼主不对,张嘴就骂人也不对,与诸君共勉了
    liuzhaowei55
    liuzhaowei55
    Apr 25, 2019❤️2
    19
    @liprais 就是看不惯讽刺的这些人,自己没有真实的处理过这种问题,只看楼主描述不懂难点问题在哪里可以理解,你不要讲话就好了,自然会有明白的人出来解决问题比如二楼,现在我就想那个讽刺楼主的人,自己好好想想这个问题怎么解决吧,自己真实遇到这个问题了是不是能很好的解决。
    Patrick95
    Patrick95
    Apr 25, 2019
    20
    还腆着脸嘲讽楼主,楼主起码有开源项目。
    你们呢,就一张嘴吗
    neoblackcap
    neoblackcap
    Apr 25, 2019
    21
    用 SQL 实现不是不行,不过太复杂了,而且不好维护。像 12 楼的写法,过一个月之后再来看看没有注释的版本,大家觉得可以一眼就看出是怎么回事?
    老实建汇总表,那么天天跑个定时任务脚本就可以了,简单易维护。
    yjxjn
    yjxjn
    Apr 25, 2019
    22
    @lihongjie0209
    @kisshere
    @thisisgpy
    @zhoujunjie221
    @kifile
    @goodbye1014ac
    @cjlmwcy 都舔着脸嘲讽 LZ,键盘侠!
    fangxing204
    fangxing204
    Apr 25, 2019 via Android
    23
    可以直接 group by 按范围的,https://stackoverflow.com/q/21421973/5615038
    mamahaha
    mamahaha
    Apr 25, 2019
    24
    如果用 laravel,这个很方便,可以查询介于时间戳 xxxxxxxx 和 yyyyyyyyy 之间生成的用户
    DB::table('users')->whereBetween('created_at',[ xxxxxxxxx,yyyyyyyyyy])->get();
    victrec
    victrec
    Apr 25, 2019
    25
    最直接的时间戳转成时间再按情况取年月日进行 GROUP BY。不过具体到用,还得看数据多不多,多的话这么搞要炸,楼上说的对,写定时任务记下每天的数量,数据多了每小时统计一把。
    Raymon111111
    Raymon111111
    Apr 25, 2019
    26
    如果只需要数量的话就缓存是最简单的

    每天一个 key, 注册一个 +1

    然后要什么 7 天 30 天的数据就直接在缓存里找就行了

    如果需要更快捷的就再每天 0 点的时候算一个统计的数量
    funky
    funky
    Apr 25, 2019
    27
    redis bitmap
    lihongjie0209
    lihongjie0209
    Apr 25, 2019
    28
    @yjxjn 我就是说了一下 楼主应该不是开发 这就是嘲讽了?有多玻璃心啊

    这种问题本来就是一个应用开发应该知道的:

    1. 要么数据库查询的时候先转化成 date 类型, 再 groupBy, 数据量大的话可能会有性能问题
    2. 要么数据库查询的时候直接用 时间戳 范围, 再在代码里面汇总。
    3. 至于说定时任务和汇总表, 其实原理和上面的一样, 不过就是加了一个缓存而已。

    这个问题的本质就是时间戳和日期的转化, 作为一个应用开发不知道时间戳?我怀疑楼主不是开发而可能是其他岗位临时使用数据库而已。

    屁大点事,就 JJYY 的。
    bwn123
    bwn123
    Apr 25, 2019
    29
    不说动手能力,你应该连了解都没了解过开发流程吧
    jessun1990
    jessun1990
    Apr 26, 2019 via iPhone
    30
    你应该是产品!
    ccl945
    ccl945
    Apr 26, 2019
    31
    别解释了,你就是一个前台客服!
    jswh
    jswh
    Apr 26, 2019
    32
    让开发下载下来然后 excel 处理
    jswh
    jswh
    Apr 26, 2019
    33
    @jswh 手动狗头
    NowTime
    NowTime
    OP
    Apr 26, 2019
    34
    @cjlmwcy 感谢
    NowTime
    NowTime
    OP
    Apr 26, 2019
    35
    @shuax
    @liuzhaowei55
    @neoblackcap
    @Raymon111111
    感谢各位建议,我算是业余的开发吧...我只是凭自己兴趣写的一个小小的项目,我以为能够直接使用 SQL 语句查询到每天的返回会结果,结果我还是太年轻,向各位大佬学习了!
    GreatLiXin
    GreatLiXin
    Jul 11, 2019
    36
    @NowTime
    我有一个比较省力的解法,今天我和你遇到了同样的问题
    我们要统计每一天的 testCase Fail 的数量,同样,有时候会没有 Fail 的 case,这时候就会发现当天的日期直接在查询结果中消失。
    在想了一下午后,我写出来了如下查询语句。很快捷也很简单。
    ```
    SELECT
    count(IF(status = false,true,null)) AS "Fail"
    FROM function_test
    GROUP BY date_time
    ```
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1905 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 90ms · UTC 15:25 · PVG 23:25 · LAX 07:25 · JFK 10:25
    ♥ Do have faith in what you're doing.