Запрос SQL, который выбирает всех неактивных пользователей - PullRequest
3 голосов
/ 02 марта 2011

У меня есть запрос для реализации.

У меня есть 2 таблицы: user и login_logs table.

Таблица user выглядит следующим образом:

id || first_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 ]

7 голосов
/ 02 марта 2011

Сначала ваш запрос должен включать всех пользователей, поэтому включите его в ЛЕВОЕ СОЕДИНЕНИЕ.

Далее ваш запрос должен использовать GROUP BY, чтобы получить МАКСИМАЛЬНОЕ время входа в систему для пользователя.

В-третьих, не помещайте функцию даты в столбец - она ​​не помогает производительности, вместо этого индексируйте столбец даты и создайте дату для проверки.

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; поэтому запись (пользователь) показывает.

0 голосов
/ 02 марта 2011
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...