选择所有非活动用户的 Sql 查询
Posted
技术标签:
【中文标题】选择所有非活动用户的 Sql 查询【英文标题】:Sql query that selects all inactive users 【发布时间】:2011-03-02 10:23:25 【问题描述】:我有一个查询要实现。
我有 2 个表:user 和 login_logs 表。
user 表如下所示:
身份证 || 名字 || 姓氏 || 电子邮件 || 用户名 || 激活 || 暂停
1 ||约翰 ||丹 || john@whatever ||约翰1 || 1 || 0 ||
2 ||迈克 ||赫特 || mike@whatever ||麦克1 || 1 || 0 ||
等等
login_logs 表如下所示:
id || login_datetime || user_id
1 || 2011-01-27 23:04:59 || 1
2 || 2010-01-27 23:04:59 || 2
等等
所以 login_logs 表会记录用户何时登录。
现在我要进行查询以选择所有非活动用户。非活跃用户是:
1) 90 天未登录的用户
2) 从未登录过的用户
我做了一个满足第一个条件但不完全正确的查询:
SELECT DISTINCT u.id, u.last_name, u.first_name, u.email,u.username
FROM users u INNER JOIN login_logs l ON l.user_id = u.id
WHERE u.activated = 1 AND u.suspended = 0 AND DATEDIFF(CURDATE(), l.login_datetime) <= 90
ORDER BY u.last_name, u.first_name, u.id
上面的查询不正确,因为如果我很久以前登录过,但最近它会将我视为非活动用户,因为它看到我很久以前登录过。
所以我想修正我上面描述的错误,同时满足第二个条件(选择从未登录过的人)。
【问题讨论】:
【参考方案1】:首先,您的查询需要包含所有用户,因此将其转换为 LEFT JOIN。
接下来,您的查询需要使用 GROUP BY 来获取每个用户的 MAX 登录时间。
第三,不要将日期函数放在列上 - 它不会提高性能,而是索引日期列并构造一个日期来测试。
SELECT u.id, u.last_name, u.first_name, u.email, u.username
FROM users u
LEFT JOIN login_logs l ON l.user_id = u.id
WHERE u.activated = 1 AND u.suspended = 0
GROUP BY u.id, u.last_name, u.first_name, u.email, u.username
HAVING IFNULL(max(l.login_datetime), 0) <= ADDDATE(CURDATE(), interval -90 day)
ORDER BY u.last_name, u.first_name, u.id
最后一部分IFNULL(max(l.login_datetime), 0)
确保如果LEFT JOIN导致login_logs中没有记录(从未登录),它将使用日期0代替测试,显然是<= 90 days ago
;因此记录(用户)显示。
【讨论】:
我觉得效果很好!非常感谢网络维基!虽然我必须研究查询,因为我不知道有子句!谢谢!【参考方案2】:select u.* from user u left outer join login l
on u.id = l.user_id
where l.user_id is null
or DATEDIFF(CURDATE(), l.login_datetime) <= 90
【讨论】:
如果他/她在过去 90 天内多次登录,这将多次选择同一用户。 谢谢萨钦!现在它选择了从未登录过的用户。但是我很久以前登录过的情况呢,但最近它把我视为非活动用户,因为它看到我很久以前登录过??以上是关于选择所有非活动用户的 Sql 查询的主要内容,如果未能解决你的问题,请参考以下文章