You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL月度用户统计需求:按日去重用户后计算月度总数

解决MySQL月度用户日维度去重统计问题

我明白你的需求啦——要统计每个月里,用户按日期去重后的记录数,同一用户同一天多条只算1次,不同日期的分别计数对吧?这其实分两步就能搞定:先拿到每个用户每天的唯一记录,再按月统计这些唯一记录的总数。

核心思路

  1. 先从原表中提取出所有user_id和对应的日期(只保留年月日部分,忽略时分秒),并去重——这样每个用户每天只会留下一条记录。
  2. 基于第一步的结果,按月分组统计总数,就是你要的最终统计数。

具体SQL示例

假设你的表名为user_records,存储记录时间的字段是record_date,下面是针对2017年9月的查询:

SELECT 
    DATE_FORMAT(record_date, '%Y-%m') AS month,
    COUNT(*) AS unique_user_day_count
FROM (
    -- 子查询:获取每个用户每天的唯一记录
    SELECT DISTINCT 
        user_id,
        DATE(record_date) AS record_day
    FROM user_records
    WHERE record_date >= '2017-09-01' 
      AND record_date < '2017-10-01' -- 用这个写法比BETWEEN更严谨,避免时分秒问题
) AS daily_unique
GROUP BY month;

如果你习惯用GROUP BY来实现去重,子查询也可以写成这样(效果完全一样):

SELECT 
    DATE_FORMAT(record_date, '%Y-%m') AS month,
    COUNT(*) AS unique_user_day_count
FROM (
    SELECT 
        user_id,
        DATE(record_date) AS record_day
    FROM user_records
    WHERE record_date >= '2017-09-01' 
      AND record_date < '2017-10-01'
    GROUP BY user_id, record_day -- 按用户+日期分组,自动去重
) AS daily_unique
GROUP BY month;

效果验证

拿你举的例子来说:

  • user_id=1在9月有2个不同日期的记录,子查询会生成2条记录
  • user_id=2在9月有2个不同日期的记录,子查询会生成2条记录
  • 外层COUNT(*)会统计这4条记录,最终返回的unique_user_day_count就是4,完全符合你的需求。

扩展:统计所有月份

如果不需要限定单个月份,去掉WHERE条件即可,查询会自动按每个月分组统计:

SELECT 
    DATE_FORMAT(record_date, '%Y-%m') AS month,
    COUNT(*) AS unique_user_day_count
FROM (
    SELECT DISTINCT 
        user_id,
        DATE(record_date) AS record_day
    FROM user_records
) AS daily_unique
GROUP BY month
ORDER BY month;

内容的提问来源于stack exchange,提问作者Shahid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:34:45