T-SQL Получить последнюю дневную метку времени по ID
У нас есть таблица действий пользователей. Каждое действие регистрируется по идентификатору пользователя, отметке времени и идентификатору активности. Пользователь может иметь несколько строк для каждого идентификатора активности каждый день.
То, что мы пытаемся сделать, это получить последний раз, когда конкретное действие было выполнено пользователем за последние X дней, как в следующем примере:
userID timestamp activityID
3241 10/14/2017 7:17 2
3241 10/15/2017 8:17 2
3241 10/16/2017 8:17 2
4355 10/15/2017 8:17 2
4355 10/16/2017 8:17 2
4355 10/17/2017 8:17 2
1234 10/15/2017 8:17 2
2236 10/15/2017 8:17 2
2236 10/16/2017 8:17 2
2002 10/17/2017 8:17 2
Я могу получить самый последний раз, когда действие было выполнено по идентификатору пользователя, но не для каждого дня в течение последних X дней:
select t1.[userID],
t2.[mxdate]
from TableA t1
inner join
(
select max([timestamp]) AS mxdate,
[userID]
from TableA
where activityType = 2
group by [userID]
) t2
on t1.[userID] = t2.[userID]
and t1.[timestamp] = t2.mxdate
Я пробовал разные способы группировки дат по временным меткам, но пока не увенчался успехом. Я продолжаю получать каждое действие и метку времени для этого.
Я направляюсь в правильном направлении по крайней мере? Если да, то какую часть / статью мне не хватает?
Заранее спасибо за любую помощь!
1 ответ
Группируя по части DATE вашей временной метки, вы можете получить максимальную временную метку для каждого действия:
;WITH cte ( userid, [day], activityid, [timestamp] ) AS (
SELECT t.userid, [day] = CONVERT(NVARCHAR, t.timestamp, 101), t.activityid, MAX(t.timestamp)
FROM MyTable t
GROUP BY t.userid, CONVERT(NVARCHAR, t.timestamp, 101), t.activityid
)
SELECT *
FROM cte
WHERE cte.activityid = 2
Необходимо было преобразовать метку времени (предположительно DATETIME
построить) до ДАТЫ, чтобы по мере роста таблицы и охвата нескольких месяцев вы не группировались в один и тот же день в два разных месяца.
Использование производной таблицы в одном запросе:
SELECT t.userid, t.activityid, t.timestamp
FROM (SELECT i.userid, i.activityid, maxTS = MAX(i.timestamp)
FROM MyTable i
GROUP BY i.userid, i.activityid, CONVERT(DATE, i.timestamp)) maxRows
INNER JOIN MyTable t
ON maxRows.userid = t.userid
AND maxRows.activityid = t.activityid
AND maxRows.maxTS = t.timestamp
WHERE t.activity = 2