【问题标题】:Count distinct records but only 1 time every XX Days计算不同的记录,但每 XX 天只计算 1 次
【发布时间】:2016-12-16 01:41:06
【问题描述】:

编辑:开始日期为 XXXX 年 1 月 1 日

我需要根据 7 天分组创建不同用户 ID 的计数。基本上,如果用户在每月的第 1 天和第 2 天致电,他们将被计为 1 次。但是,如果他们在第 1 天和第 10 天打电话,那么他们会被计算 2 次。

表格布局:

userId         CallId        datetime
0              123            01/01/2016 xx:xx:xx
0              124            01/10/2016 xx:xx:xx
1              125            01/10/2016 xx:xx:xx
1              126            01/10/2016 xx:xx:xx
2              127            01/10/2016 xx:xx:xx
1              128            01/30/2016 xx:xx:xx
2              129            01/31/2016 xx:xx:xx

我需要返回的样子:

Count(UserID)  Week#
      1          1
      3          2
      2          4

感谢您的宝贵时间。

【问题讨论】:

  • 对于给定年份的计算,您的一周应该从哪里开始?
  • 这取决于您何时“开始”这 7 天的区块。即,对于像 {--111---1-------1----------1--------} 这样的数据,如果您从一开始 {--111- --1---- ---1--- ------- 1------ --} = 4 的计数将不同于您在 3 天开始时的计数:{-- 111---1 ------- 1------ ----1-- ------} = 3。
  • 为了简单起见,我会在 XXXX 年 1 月 1 日开始它
  • 我可能会做一个循环.....仍然在这里集思广益。
  • 我不认为查询应该与 UserId 相关,但 week# 仅基于给定的结果。请参阅下面的查询

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


【解决方案1】:

根据 Gurwinders 的回复,我制作了以下年份并包括在内,以便它在几年后仍然可用。

SELECT COUNT(UserID), CallYear, CallWeek
FROM (
SELECT DISTINCT UserID, 
                datepart(year,datetime) as CallYear,
                datepart(week,datetime) as CallWeek
FROM my_table
      )
Group By CallYear,CallWeek

【讨论】:

    【解决方案2】:

    这将从 1 月 1 日开始产生滚动不同计数

    Declare @YourTable table (userId  int,CallId int,datetime datetime)
    Insert Into @YourTable values
    (0,123,'2016-01-01'),
    (0,124,'2016-01-10'),
    (1,125,'2016-01-10'),
    (1,126,'2016-01-10'),
    (2,127,'2016-01-10'),
    (1,128,'2016-01-30'),
    (2,129,'2016-01-31')
    
    Select D1
          ,D1 =DateAdd(DD,6,D1)
          ,Cnt=count(Distinct UserID)
     From  @YourTable A
     Join (Select Top 500 D1=DateAdd(DD,(Row_Number() Over (Order By Number)-1)*7,'2016-01-01') From master..spt_values ) B
       on  datetime between D1 and DateAdd(DD,6,D1)
     Group By D1
    

    返回

    D1         D1           Cnt
    2016-01-01 2016-01-07   1
    2016-01-08 2016-01-14   3
    2016-01-29 2016-02-04   2
    

    【讨论】:

    • 太棒了,我也会试试这个。我正在推进 Gurwinder 的示例,它似乎正在工作。但是我想试试这个,因为我还没有写过这样的代码。
    • @user1949329 很高兴为您提供帮助,只需稍加改动,您就可以将一周定义为周一至周日
    • @user1949329 只是一个想法,你也可以有一个滚动的 n 天窗口,即每 10 天甚至 14 天
    【解决方案3】:

    你可以用这个:

    select count(distinct userid), datepart(week, datetime) week, datepart(year, datetime) year
    from my_table
    group by datepart(week, datetime), datepart(year, datetime);
    

    【讨论】:

    • 这不计入他的用户在同一周内调用两次的用​​例,它们应该只计入一次。
    • 感谢您的回复,但这不符合我的要求。
    • @user1949329 已更新。你能再试一次吗?
    • 所以我的总历史大约是 8 年的数据,这只会计算一次,不会考虑间隔数周的多次调用。
    • 那你也得拿一年。我会更新答案
    【解决方案4】:

    你的开始日期是什么时候?你看过 DateDiff() 函数吗?

    【讨论】:

    • 我看过 Datediff,现在正在尝试不同的分组方法。然而,它的独特部分让我失望
    • 如果您使用星期部分选择了 DateDiff(),您可以对其进行分组,并选择不同用户 ID 的计数
    【解决方案5】:

    试试这个:

    With ABC As (select datepart(week, datetime) as week# from table) Select count(week#) as Times,week# From ABC

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-05
      • 2012-03-03
      • 2022-10-04
      • 1970-01-01
      • 2021-09-23
      • 2012-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多