我有一个像这样的登录表:
Date,UserID
2020-08-01,1
2020-09-01,1
2020-09-07,2
2020-10-01,3
2020-10-12,4
2020-10-25,1
基本上,每次用户登录我的应用程序时,它都会注册日期
和用户ID
。我需要知道活跃用户的数量。对我来说,活跃用户是指在上周的前三十天内每天登录的用户。例如,假设我们计算的本周是从 2020-10-09(2020 年 10 月 9 日)到 2020-10-15(2020 年 10 月 15 日)。然后我会这样:
检查用户 ID = 1:
- 用户在(“2020-10-09” - 30)和“2020-10-09”之间的任何时间登录
- 用户在(“2020-10-10” - 30)和“2020-10-10”之间的任何时间登录
依此类推直至2020年10月15日
然后,每个用户 ID 的情况都是相同的。
换句话说,我检查一周内 30 天的滑动窗口中登录的用户数量。我希望这是有道理的。
这就是我的想法:
DROP TABLE IF EXISTS #ActiveUsers
CREATE TABLE #ActiveUsers (UserID bigint)
DECLARE @lowerDate Datetime='2020-10-09'
DECLARE @upperDate Datetime='2020-10-15'
DECLARE @activeSpan int=30
WHILE(@lowerDate <= @upperDate)
BEGIN
SELECT e.UserID INTO #ActiveUsers FROM
(SELECT DISTINCT(UserID) FROM logins WHERE Date >= (@lowerDate - @activeSpan)) AS e
WHERE e.UserID NOT IN (SELECT UserID FROM #ActiveUsers)
SET @lowerDate = @lowerDate + 1
END
PRINT SELECT COUNT(*) FROM #ActiveUsers
我的推理是这样的:
- 检查时间范围内的唯一用户 ID。
- 将唯一的插入到临时表中作为 ling,因为它们之前没有插入过
- 循环选择日期后计算总数。
但除了安静不优雅之外,我无法让它发挥作用。
我会感谢任何建议。
谢谢!
最佳答案
我不确定我是否理解该要求 - 但让我确认一下我的理解
假设您的“upperDate”是 10 月 7 日。这意味着您想要检查用户是否已完成以下所有操作
- 已在 9 月 1 日至 10 月 1 日期间登录
- 已在 9 月 2 日至 10 月 2 日期间登录
- ...
- 已在 9 月 7 日至 10 月 7 日期间登录
现在,想象三个用户,他们都只登录过一次
- 首次登录时间为 9 月 20 日
- 第二次登录于 9 月 3 日
- 第三位登录者于 10 月 3 日登录
他们的结果如下
- 第一个被视为活跃,因为它们被所有 7 次测试识别出来。
- 第二个不会被视为活跃,因为他们未通过“9 月 4 日至 10 月 4 日”及之后的测试。
- 第三个不会被视为活跃,因为他们未通过“9 月 1 日至 10 月 1 日”和“9 月 2 日至 10 月 2 日”的测试。
换句话说 - 我认为您需要做的就是找到上日期减去 30 天
到上日期减去 7 天
之间的登录信息。
因此,您不需要循环 - 最简单的检查是
DECLARE @upperDate Datetime = '20201015';
DECLARE @activeSpan int = 30;
SELECT DISTINCT(UserID)
FROM logins
WHERE [Date] >= DATEADD(day, - @activeSpan, @upperDate)
AND [Date] <= DATEADD(day, -7, @upperDate);
关于sql-server - T-SQL 计算时间窗口内的事件数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64827895/