我有一张CustomerID
,StartDate
和EndDate
的桌子。
我正在尝试创建包含以下列的表:Date
,ActiveUsers
。
Date
必须是2016年1月1日至今天之间的所有日期。 ActiveUsers
是CustomerID
的计数,其中Date
介于StartDate
和EndDate
之间。
我希望所有这些都有意义。
我找到了可以为我提供日期列表的代码,但是我不知道如何将我的客户表加入此结果。
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
答案 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,以获取有关如何为自己创建一个的逐步说明。