使用SQL计算定期用户12个月

时间:2019-01-31 17:51:36

标签: sql sql-server sql-server-2012

我正在尝试查看是否有更好的方法来实现我现在正在做的事情。例如,我需要知道过去12个月内已登录的用户总数。因此,每个连续至少十二个月每月登录一次的用户都将计入总数。

我现在这样做的方式是:查询表并获取所有用户ID和时间戳(它们处于活动状态),然后将其返回给我的C#代码。然后,使用一堆循环和LINQ来计算值(将太多的代码转储到此问题中,并且由于我试图摆脱在c#中的处理方式,因此我认为不需要这样做)。

现在这需要一些时间才能运行,我敢肯定必须有一种更好的SQL方式来执行此操作。我已经搜索过,但没有找到可让您根据重复条件进行计数的任何SQL函数。

对于一个答案,我希望得到一个示例或一个类似的SO问题的链接,或者是一篇有关实现此问题的文章。

MyUsersTable的示例:

UserId | Timestamp
1      | '2018-12-23 00:00:00.000'
1      | '2018-11-23 00:00:00.000'
1      | '2018-10-23 00:00:00.000'

编辑:我确实考虑过使用SUM(CASE WHEN month = 1 and month = 2 and month = 3),但这似乎也不是一个很好的解决方案。

预期结果:

过去12个月每月至少活跃一次的用户总数。

3 个答案:

答案 0 :(得分:2)

如果您需要在2018年每月登录的用户:

select ut.userid
from MyUsersTable ut
where timestamp >= '2018-01-01' and timestamp < '2019-01-01'
group by ut.userid
having count(distinct month(timestamp)) = 12;

答案 1 :(得分:2)

我将计算用户登录的不同月份:

SELECT   userid
FROM     mytable
WHERE    YEAR(timestamp) = 2018
GROUP BY userid
HAVING   COUNT(DISTINCT MONTH(timestamp)) = 12

答案 2 :(得分:1)

要获取连续特定月份登录的用户ID,可以使用:

/* 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
;

分贝<>拨弄here 我的例子。

第一个声明的两个变量是您的输入变量。您可以在运行报表的日期输入它,然后告诉它要返回多少个月。因此,您可以搜索任意数量的月份。之后,几乎是日期操作和数学运算。

@EndDate实际上是获取您声明的日期并计算当前正在搜索的月份的第一天。您将搜索该日期之前的任何日期。

@StartDate@EndDate开始倒数,以计算要搜索的月数。

您的子选择中的

(YEAR(userLoginDT)*100)+MONTH(userLoginDT)创建了一个整数变量,您可以GROUP BY来获取正在搜索的月份的不同计数。这部分可以通过日历表加快。

然后你只需要使用HAVING挑出多少重复的记录您想为@monthsToSearch


注意::这里有很多人可以证明,在处理日期计算和大量搜索数据时,我非常喜欢使用日历表。类似的东西可能会加快查询了一下。