繁体   English   中英

选择所有非活动用户的SQL查询

[英]Sql query that selects all inactive users

我有一个查询要实现。

我有2个表: userlogin_logs表。

用户表如下所示:

id || first_name || last_name || 电子邮件 || 用户名 || 激活 || 暂停

1 || 约翰|| 丹|| john @ whatever || john1 || 1 || 0 ||

2 || 迈克|| 哈特|| mike @ whatever || mike1 || 1 || 0 ||

等等

login_logs表如下所示:

id || login_datetime || 用户身份

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

以上查询不正确,因为如果我已经登录很久以前,但最近它也把我视为非活动用户,因为它看到我在很久以前登录。

所以我想解决上面描述的错误并且还满足第二个条件(选择从未登录过的人)。

首先,您的查询需要包含所有用户,因此将其转换为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 ; 因此记录(用户)显示。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM