Чтобы получить идентификаторы пользователей, которые входили в систему в течение определенного количества последовательных месяцев, вы можете использовать:
/* These are your input values */
DECLARE @searchDate date = '2018-12-15' ;
DECLARE @monthsToSearch int = 12 ;
/* First day of search month */
DECLARE @EndDate date = DATEADD(month, DATEDIFF(month, 0, @searchDate), 0) ;
/* First day of month to search from */
DECLARE @StartDate date = DATEADD(month, -@monthsToSearch, @EndDate) ;
SELECT userID --, @StartDate AS startDate, @EndDate AS endDate
FROM (
SELECT userID, ( (YEAR(userLoginDT)*100)+MONTH(userLoginDT) ) AS datePoint /* YYYYMM */
FROM t1
WHERE userLoginDT >= @StartDate
AND userLoginDT < @EndDate
) s1
GROUP BY userID
HAVING count(distinct(datePoint)) = @monthsToSearch
;
См. db <> fiddle здесь для моих примеров.
Первые две объявленные переменные являются вашими входными переменными.Вы указываете дату, за которую запускаете отчет, а затем указываете, на сколько месяцев вы хотите вернуться.Таким образом, вы можете искать любое количество месяцев.После этого это в значительной степени манипулирование датами и математика.
@EndDate
по существу берет вашу объявленную дату и вычисляет первый день месяца, в котором вы в настоящее время ищете. Вы будете искать любые даты до этой даты.
@StartDate
отсчитывает отваш @EndDate
для расчета количества месяцев, которые вы хотите найти.
(YEAR(userLoginDT)*100)+MONTH(userLoginDT)
в вашем под-выборе создает целочисленную переменную, которую вы можете GROUP BY
, чтобы получить различное количество месяцев, в течение которых вы ищете.Эта часть может быть ускорена с помощью таблицы календаря.
Затем вы просто используете HAVING
, чтобы выбрать, сколько разных записей вы хотите для @monthsToSearch
.
ПРИМЕЧАНИЕ: Как многие здесь могут подтвердить, я большой поклонник работы с таблицами календаря при работе с расчетами дат и большими объемами поисковых данных.Нечто подобное, скорее всего, немного ускорит запрос.