【发布时间】:2022-02-24 04:31:18
【问题描述】:
我在编写一个计算任何一天的活跃客户数量的递归函数时遇到了麻烦。
假设我有一张这样的桌子:
| Client | Start Date | End Date |
|---|---|---|
| 1 | 1-Jan-22 | |
| 2 | 1-Jan-22 | 3-Jan-22 |
| 3 | 3-Jan-22 | |
| 4 | 4-Jan-22 | 5-Jan-22 |
| 5 | 4-Jan-22 | 6-Jan-22 |
| 6 | 7-Jan-22 | 9-Jan-22 |
我想返回一个如下所示的表格:
| Date | NumActive |
|---|---|
| 1-Jan-22 | 2 |
| 2-Jan-22 | 2 |
| 3-Jan-22 | 3 |
| 4-Jan-22 | 4 |
| 5-Jan-22 | 4 |
| 6-Jan-22 | 3 |
| 7-Jan-22 | 3 |
| 8-Jan-22 | 3 |
| 9-Jan-22 | 4 |
有没有办法做到这一点?理想情况下,我会有一个固定的开始日期,然后转到今天的日期。
我尝试过的一些作品:
创建递归日期表
为简单起见,截断至 2022 年 2 月 1 日:
WITH DateDiffs AS (
SELECT DATEDIFF(DAY, '2022-02-02', GETDATE()) AS NumDays
)
, Numbers(Numbers) AS (
SELECT MAX(NumDays) FROM DateDiffs
UNION ALL
SELECT Numbers-1 FROM Numbers WHERE Numbers > 0
)
, Dates AS (
SELECT
Numbers
, DATEADD(DAY, -Numbers, CAST(GETDATE() -1 AS DATE)) AS [Date]
FROM Numbers
)
我希望能够遍历该表中的日期,例如通过修改以下每个日期的查询,例如通过@loopdate。然后 UNION ALL 到一个更大的最终查询。 我现在不知道如何运行查询来计算活跃用户的数量:
SELECT
COUNT(Client)
FROM clients
WHERE [Start Date] >= @loopdate AND ([End Date] <= @loopdate OR [End Date] IS NULL)
谢谢!
【问题讨论】:
-
谢谢!我已经添加了到目前为止所做的事情。
-
见previous question。它写得很好,因为它包含一个自包含的表结构 (DDL),插入 data 来填充这些表,并且 query 尝试根据表检索数据以及预期输出。换句话说,一个完整的minimal reproducible example。 在您的问题中提供这些相同的工件将大大有助于其他人能够帮助您解决您的问题。您也可以将rextester.com 用于您的 DDL 和数据。
-
拥有一个日期/日历表会有很长的路要走,我认为值得创建一个。这是一个包含每个日期的列的表。有了它,您可以执行非常简单的逻辑,例如
SELECT calendartable.date, count(*) FROM calendartable LEFT OUTER JOIN yourtable ON calendartable.date BETWEEN yourtable.startdate and yourtable.enddate WHERE calendartable.date BETWEEN '2022-01-01' and '2022-02-28 GROUP BY calendartable.date'(例如)。 -
您的样本数据应该是 3,而不是我认为的最后一行的 4。
标签: sql sql-server