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

如何用单条SQL查询整月每日的distinct登录用户数据

整月每日登录用户列表SQL实现方案

实现逻辑

  • 将登录时间转换为目标-07:00时区后提取日期维度
  • 调整时间过滤范围覆盖整月,无需拆分多次单日查询
  • 按「日期+用户ID」分组实现单日用户去重,和原查询返回逻辑一致

方案1:逐行展示日期+对应登录用户(等价于31天单日结果拼接)

SELECT 
    -- 提取-7时区的登录日期
    DATE(CONVERT_TZ(ul.login_time, '+00:00', '-07:00')) AS `LoginDate`,
    ul.user_id,
    u.first_name,
    u.last_name,
    u.email,
    -- 可按需取用户当日首次/末次登录时间,这里取首次
    MIN(CONVERT_TZ(ul.login_time, '+00:00', '-07:00')) AS `FirstLoginTimeOfDay`
FROM users u
-- 原查询LEFT JOIN无意义,WHERE过滤登录时间后等价于INNER JOIN,直接写INNER JOIN性能更优
INNER JOIN users_logins ul 
    ON u.id = ul.user_id
WHERE 
    -- 提前用UTC时间范围过滤,可命中login_time索引,性能远高于转换时区后过滤
    -- 以下时间对应-7时区2024年8月1日00:00:00 至 2024年8月31日23:59:59
    ul.login_time BETWEEN '2024-08-01 07:00:00' AND '2024-09-01 06:59:59'
    AND u.third_party = '0'
-- 按日期+用户维度分组,保证同一用户同一天只出现一次
GROUP BY `LoginDate`, ul.user_id, u.first_name, u.last_name, u.email
ORDER BY `LoginDate` ASC, `FirstLoginTimeOfDay` ASC;

如果不需要走索引优化,也可以直接用转换后的日期做过滤,写法更直观:

WHERE 
    DATE(CONVERT_TZ(ul.login_time, '+00:00', '-07:00')) BETWEEN '2024-08-01' AND '2024-08-31'
    AND u.third_party = '0'

方案2:按日期聚合展示当日所有登录用户

如果需要每行对应一天,整行展示当天的用户列表,可以用GROUP_CONCAT实现:

SELECT 
    DATE(CONVERT_TZ(ul.login_time, '+00:00', '-07:00')) AS `LoginDate`,
    GROUP_CONCAT(DISTINCT ul.user_id ORDER BY ul.user_id SEPARATOR ',') AS `DailyLoginUserIds`,
    COUNT(DISTINCT ul.user_id) AS `DailyLoginUserCount`
FROM users u
INNER JOIN users_logins ul ON u.id = ul.user_id
WHERE 
    ul.login_time BETWEEN '2024-08-01 07:00:00' AND '2024-09-01 06:59:59'
    AND u.third_party = '0'
GROUP BY `LoginDate`
ORDER BY `LoginDate` ASC;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 23:39:04