【问题标题】:Finding Active Clients By Date按日期查找活跃客户
【发布时间】: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


【解决方案1】:

在这种特殊情况下,您不需要任何递归,您至少需要一个要报告的范围内的日期列表,最好是一个永久的日历表

出于演示的目的,您可以即时创建一些内容,并像这样使用它,并使用您外部加入到的日期列表:

with dates as (
    select top(9) 
      Convert(date,DateAdd(day, -1 + Row_Number() over(order by (select null)), '20220101')) dt
    from master.dbo.spt_values
)

select d.dt [Date], c.NumActive
from dates d
outer apply (
  select Count(*) NumActive
  from t
  where d.dt >= t.StartDate and (d.dt <= t.EndDate or t.EndDate is null)
)c

看到这个Demo Fiddle

【讨论】:

  • 编辑:我能够让它工作。太感谢了!!我已经在这几个小时了。很遗憾,我无法公开投票,但请知道我非常感激!
  • @leviosa 是的,您可以尝试 master.sys.columns demo- 但这应该不是问题,请参阅演示小提琴 - 您使用的是什么版本的 SQL Server?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-31
  • 1970-01-01
  • 2022-08-16
  • 1970-01-01
  • 2014-11-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多