SQL:用户计数的每日报告

Posted

技术标签:

【中文标题】SQL:用户计数的每日报告【英文标题】:SQL: Daily report for with user counts 【发布时间】:2016-10-04 09:50:48 【问题描述】:

我正在尝试获取 users 的 30 天报告,这将返回 datetotal count of users 作为创建的计数日期,我用这个查询做到了

 Select count(*)  As [Count] ,  
        (SELECT CONVERT(date, AddDate)) As [Date] 
 from Users 
 WHERE AddDate  >= (SELECT DateAdd(month, -1, Convert(date, GetDate()))) 
 Group By CONVERT(date, AddDate)

它只给我创建任何用户的日期,但如果它有 count 0,我想显示所有 30 天 >.

我想对月度报告做同样的情况。 我正在获得创建用户的月份,现在我想将其更改为从本月开始过去 12 个月及其总用户数。为此,我正在使用此查询

 Select count(*)  As [Count] ,
        (Select DATEPART( month , DateAdd( month , DATEPART(mm,AddDate) , -1 ) )) as Month
 from Users 
 WHERE AddDate  >= (SELECT DateAdd(YEAR, -1, Convert(date, GetDate())))
 Group By DATEPART(mm,AddDate)

【问题讨论】:

您需要Calendar tableLeft Join 【参考方案1】:

使用日历 CTE:

With NumberSequence ( Number ) as
(
    Select 1 as Number
    union all
    Select Number + 1
    from NumberSequence
    where Number <= 30
)
, CalendarCTE as
(
    select cast(dateadd(dd, -30 + Number,getdate()) as Date) as CalDate
    from Numbersequence
)

select CalDate, count(U1.*) as CountUsers
from CalendarCTE
left join Users U1
on CalDate = convert(date, U1.AddDate)
group by CalDate

【讨论】:

将“CalDate”列转换为日期,否则这也会返回时间部分。【参考方案2】:

正如我在评论中提到的,您需要 Calendar tableLeft Join

SELECT Count(u.adddate) AS [Count], 
       c.dates  AS [Date] 
FROM   calendar_table C 
       LEFT JOIN users U 
              ON c.dates = CONVERT(DATE, adddate) 
WHERE  c.dates >= Dateadd(month, -1, CONVERT(DATE, Getdate())) 
GROUP  BY c.dates 

要生成/创建日历表或日期,请查看以下问题

How to generate a range of dates in SQL Server

Generate Dates between date ranges

How to create a Calender table for 100 years in Sql

【讨论】:

日历表是多余的。为什么不是 30 天日历 CTE? @JohnHC - 这个想法是一种日历表,而不是日历表【参考方案3】:

试试这个脚本:

WITH CTEDates
AS
(
  SELECT CAST(GetDate() as date) AS [date]
  UNION ALL
  SELECT DATEADD(dd, 1, [date])
  FROM CTEDates
  WHERE DAY([date]) <= 30
)
Select count(*)  As [Count] ,CONVERT(date, AddDate) As [Date] 
from CTEDates 
LEFT JOIN Users ON CTEDates.date=CONVERT(date, AddDate)
WHERE AddDate  >= DateAdd(month, -1, GetDate())
Group By CONVERT(date, AddDate)

【讨论】:

CTE 不起作用。需要限制的是增量,而不是日期。否则,10 月 31 日将不会出现... 嗯,很高兴知道这一点,但这将给 10 月 31 日,我在发布答案之前已经测试过了 :)【参考方案4】:
DECLARE @StartDate Datetime
DECLARE @EndDate Datetime

CREATE TABLE #tMyCalanderDate (dtDate Datetime Primary key)

SELECT @StartDate = '01-Sep-2016'
SELECT @EndDate  =  '30-Sep-2016'

WHILE @StartDate <= @EndDate
BEGIN
    INSERT INTO #tMyCalanderDate (dtDate)
    SELECT @StartDate 

    SELECT @StartDate = DATEADD(day,1,@StartDate)

END

SELECT count(A.UserID)  As [Count] , B.dtDate As [Date] 
FROM Users AS A
RIGHT JOIN #tMyCalanderDate AS B ON CONVERT(date, A.AddDate) = CONVERT(date, B.dtDate)  
WHERE CONVERT(date, A.AddDate) BETWEEN @StartDate AND @EndDate
Group By CONVERT(date, B.dtDate)

【讨论】:

Azure Synapse Analytics(数据仓库)不支持 CTE 中的递归,因此可以使用此方法的变体来创建临时表,而不是此处的其他建议。 但是,这里有一个更快的方法的链接:***.com/a/7825036/1803823【参考方案5】:

您可以使用 CTE 获取三十天日历。然后离开加入你的用户表。

DECLARE @CurrentTime DATETIME = GETDATE()
;WITH CTE AS
    (
      SELECT CONVERT(DATE, @CurrentTime) AS [Date]

      UNION ALL

      SELECT  DATEADD(dd, -1, Date)
      FROM    CTE
      WHERE   DATEADD(dd, 29, Date) > @CurrentTime
    )
SELECT COUNT(U.AddDate) AS [Count]
, CTE.[Date] AS [Date]
FROM CTE
LEFT JOIN users U
ON CTE.Date = CONVERT(Date, AddDate)
GROUP BY CTE.Date

您可以使用类似的 CTE 来获取十二个月的日历,并使用相同的联接来获取计数。

HTH。

【讨论】:

以上是关于SQL:用户计数的每日报告的主要内容,如果未能解决你的问题,请参考以下文章

SQL将重复的行报告为计数

sql 报告波形汇总计数

按名称查询报表的 SQL 查询,其中许多列按状态计数

SQL 将库存计数表连接到日期表

如何优化访问计数器 SQL 查询?

每天访问我的商店 4 次或超过 4 次的 user_id 的每日计数