Sql server T-SQL计数时间窗口中的事件数

Sql server T-SQL计数时间窗口中的事件数,sql-server,tsql,sliding-window,Sql Server,Tsql,Sliding Window,我有这样一个登录表: 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日。然后我会这样说: Date,Us

我有这样一个登录表:

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日。然后我会这样说:

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

检查UserID=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
我的推理是这样的:

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

检查时间范围内的唯一用户标识。 在临时表中插入以前未插入的唯一表 循环计算选定日期后的总数。 但除了安静不雅之外,我还没能让它起作用

我愿意接受任何建议


谢谢大家!

我不确定我是否理解该要求,但让我确认一下我的理解

让我们假设你的“截止日期”是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日”的测试。 换句话说,我认为你所需要做的就是找到upperdate减去30天到upperdate减去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);

谢谢@seanb。我正试图用这种方法解决问题,但我会尝试一下。非常感谢!我不是百分之百,顺便说一句,它做你想做的事。我让它按照我对你的问题的理解来做,但逻辑听起来不正确,例如,作为一个“主动”检查,很奇怪,示例中的第三个用户会被排除在外。如果你能展示一下我所举的例子,例如,三个用户和你想要的结果,那就太好了。