SQL活动用户(按天)

时间:2019-03-08 09:00:44

标签: sql-server tsql

我有一张CustomerIDStartDateEndDate的桌子。
我正在尝试创建包含以下列的表:DateActiveUsers

Date必须是2016年1月1日至今天之间的所有日期。 ActiveUsersCustomerID的计数,其中Date介于StartDateEndDate之间。

我希望所有这些都有意义。

我找到了可以为我提供日期列表的代码,但是我不知道如何将我的客户表加入此结果。

DECLARE @StartDateTime DATE
DECLARE @EndDateTime DATE

SET @StartDateTime = '2016-01-01'
SET @EndDateTime = GETDATE();

WITH DateRange(DateData) AS 
(
    SELECT @StartDateTime as Date
    UNION ALL
    SELECT DATEADD(d,1,DateData)
    FROM DateRange 
    WHERE DateData <= @EndDateTime
)
SELECT dr.DateData
FROM DateRange dr
OPTION (MAXRECURSION 0) 
GO

1 个答案:

答案 0 :(得分:0)

这是一个简单的左联接,按和计数:

SELECT DateData, COUNT(CustomerID) as ActiveUsers
FROM DateRange AS D
LEFT JOIN Customers AS C 
    ON D.DateData >= C.StartDate 
    AND D.DateData <= C.EndDate
GROUP BY DateData

不过,这里有个免费的提示:在范围较小时,使用递归cte进行类似的操作就可以了,但是如果发现自己必须使用OPTION (MAXRECURSION 0),则意味着存在性能下降的危险,因为递归cte,应将其替换为基于理货表的解决方案。

如果您不知道统计表是什么,请阅读Jeff Moden的The "Numbers" or "Tally" Table: What it is and how it replaces a loop.
如果您还没有统计表,请阅读What is the best way to create and populate a numbers table?

说过,与日期相关的查询通常受益于预先填充的日历表-这样的表可以节省您计算周末,国定假日等的时间,而在现代服务器中,存储价格几乎可以忽略不计。 阅读亚伦·伯特兰(Aaron Bertrand)的Creating a date dimension or calendar table in SQL Server,以获取有关如何为自己创建一个的逐步说明。