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

时间:2011-03-02 10:23:26

标签: mysql sql

我有一个要执行的查询。

我有2个表:用户 login_logs 表。

用户表格如下所示:

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

1 ||约翰·||丹||约翰@无论|| john1 || 1 || 0 ||

2 ||迈克||赫特||迈克@无论|| mike1 || 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

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

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

2 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:0)

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