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

Posted

技术标签:

【中文标题】选择所有非活动用户的 Sql 查询【英文标题】:Sql query that selects all inactive users 【发布时间】:2011-03-02 10:23:25 【问题描述】:

我有一个查询要实现。

我有 2 个表:userlogin_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代替测试,显然是&lt;= 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 查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL BigQuery:选择基于时间的查询

从日期中选择特定记录的 SQL 查询

sql查询:选择timeMade超过hoursNeeded的所有用户

我无法将 SQL 选择查询结果转换为位

Sql查询选择这个用户所在的每个组内每个人的所有消息

SQL 查询术语?