2015-02-07 5 views
0

У меня есть таблица user с колонкой login_time.Выбрать между датами с условием подсчета

Я хочу выбрать всех пользователей, которые зарегистрировались более 10 раз в месяц.

Я пытался что-то вроде этого:

SELECT login_time, count(id) as loginCount FROM user 

WHERE login_time between DATE_SUB(login_time INTERVAL 1 month) AND login_time 

GROUP BY id, MONTH(login_time) HAVING loginCount > 10; 

Im не уверен, что о моем выборе между датами. Как я могу выбрать интервалы между месяцами, избегая двойных записей. Например, если у меня это значения для login_time:

1. '2015-02-01 14:05:19' 
2. '2015-01-21 14:05:19' 
3. '2015-01-11 14:05:19' 

Оба 3 и 2 находятся в пределах месячного диапазона 1. Так я получу двойные записи для того, что ценности?

+0

Является ли 'GROUP BY id' намеренно? Это предотвращает группировку в целом, если речь идет только о одной таблице. Также 'WHERE login_time BETWEEN x AND login_time' по существу' WHERE login_time = login_time', который всегда совпадает. – Caramiriel

+0

Я не понимаю. Вы сохраняете количество попыток входа пользователя в другую таблицу? – karlingen

+0

@karlingen да, его в другой таблице – dasdasd

ответ

1

Чтобы найти пользователей, которые вошли в систему более десяти раз в течение месяца, заканчивающегося прямо сейчас, сделайте это.

SELECT COUNT(*) times_logged_in, 
     userid 
    FROM user 
WHERE login_time >= NOW() - INTERVAL 1 MONTH 
GROUP BY user_id 
HAVING COUNT(*)> 10 

Чтобы найти пользователей, которые зарегистрировались более десяти раз в любом календарном месяце в вашем столе, сделайте это.

SELECT COUNT(*) times_logged_in, 
     DATE(DATE_FORMAT(login_time, '%Y-%m-01')) month_beginning, 
     userid 
    FROM user 
GROUP BY user_id, DATE(DATE_FORMAT(login_time, '%Y-%m-01')) 
HAVING COUNT(*)> 10 

Хитрость здесь выражение DATE(DATE_FORMAT(login_time, '%Y-%m-01')), который преобразует любую метку времени в первый день месяца, в котором оно происходит.

Ваш вопрос упомянул об этом WHERE условие:

WHERE login_time between DATE_SUB(login_time INTERVAL 1 month) AND login_time 

Это ничего интересного не делать, потому что он всегда возвращается правда. Каждый заданный login_time всегда попадает в указанный вами интервал.

Редактировать: Вы можете GROUP BY MONTH(dt) если хотите. Но способ, которым я показал это автоматически, составляет годы, а также месяцы, поэтому, на мой взгляд, это намного лучше для точной отчетности.

Другое редактирование: Эта формула дает предыдущее воскресенье для любой заданной даты или метки времени.

FROM_DAYS(TO_DAYS(login_time) -MOD(TO_DAYS(login_time) -1, 7)) 

Если понедельник первый день недели в вашей юрисдикции, изменить -1 к -2. Группировка по этой функции превосходит выполнение GROUP BY WEEK(login_time), потому что WEEK() делает странные вещи в начале и конце календарных лет.

Это все написано в более подробно здесь: http://www.plumislandmedia.net/mysql/sql-reporting-time-intervals/

+0

Спасибо. Я понимаю, что мое место было плохим. Могу ли я использовать в 'GROUP BY' следующее:' MONTH (login_time) 'вместо' DATE (DATE_FORMAT (login_time, '% Y-% m-01')) ' – dasdasd

+1

Просьба посмотреть мое редактирование, чтобы ответить на ваш вопрос. –

+0

Спасибо, отличный ответ. – dasdasd

Смежные вопросы