为不同时间段的每个相关记录计算 db 中的行数

Posted

技术标签:

【中文标题】为不同时间段的每个相关记录计算 db 中的行数【英文标题】:Count number of rows in db for each corelated record for different time periods 【发布时间】:2020-08-28 11:38:57 【问题描述】:

我正在努力寻找适合这种情况的最佳解决方案。 我必须将帐户和事件以 1:N 的方式相互关联。 我想要一个查询,它可以在不同的时间段内提供具有打开状态、关闭状态等的事件总数。例如,过去 15 天打开的门票,过去 30 天打开的门票。 预期输出示例(未显示所有列):

`+--------------+---------------+---------------+----------------+-----------------+
| TckOpenLast7 | TckOpenLast15 | TckOpenLast30 | TckClosedLast7 | TckClosedLast15 |
+--------------+---------------+---------------+----------------+-----------------+
|        40463 |        50463  |         60463 |        4       |               8 |
+--------------+---------------+---------------+----------------+-----------------+`

所以我尝试了下面这个简单的查询并给出了正确的结果,但我需要一个更优雅、性能更好的查询。

Select TckOpenLast7= (Select Count(incidentId) From Incident where CreatedOn >= DATEADD(DAY, -7, GETDATE()) And statecode=0 And CustomerId=@Accid),
TckOpenLast15=(Select  Count(incidentId) From Incident where CreatedOn >= DATEADD(DAY, -15, GETDATE() )And statecode=0 And CustomerId=@Accid),
TckOpenLast30=(Select  Count(incidentId) From Incident where CreatedOn >= DATEADD(DAY, -30, GETDATE()) And statecode=0 And CustomerId=@Accid),
TckClosedLast7=(Select  Count(incidentId) From Incident where CreatedOn >= DATEADD(DAY, -7, GETDATE()) And statecode=1 And CustomerId=@Accid),
TckClosedLast15=(Select  Count(incidentId) From Incident where CreatedOn >= DATEADD(DAY, -15, GETDATE()) And statecode=1 And CustomerId=@Accid),
TckClosedLast30=(Select  Count(incidentId) From Incident where CreatedOn >= DATEADD(DAY, -30, GETDATE()) And statecode=1 And CustomerId=@Accid),
TckInProcessLast7=(Select  Count(incidentId) From Incident where CreatedOn >= DATEADD(DAY, -7, GETDATE()) And statecode=1 And CustomerId=@Accid),
TckInProcessLast15=(Select  Count(incidentId) From Incident where CreatedOn >= DATEADD(DAY, -15, GETDATE()) And statecode=1 And CustomerId=@Accid),
TckInProcessLast30=(Select  Count(incidentId) From Incident where CreatedOn >= DATEADD(DAY, -30, GETDATE()) And statecode=1 And CustomerId=@Accid)

我正在开发一个使用 ADO.Net 连接从 sql server 数据库中检索数据的 SSIS 包。

【问题讨论】:

【参考方案1】:

使用条件聚合:

select sum(case when CreatedOn >= DATEADD(DAY, -7, GETDATE()) and state = 0
                then 1 else 0
           end) as TckOpenLast7,
       sum(case when CreatedOn >= DATEADD(DAY, -15, GETDATE()) and state = 0
                then 1 else 0
           end) as TckOpenLast15,
       . . .
From Incident
where CustomerId = @Accid;

为了提高性能,您需要在(CustomerId) 甚至(CustomerId, state, CreatedOn) 上建立索引。

另外:请注意GETDATE() 有一个时间组件。我猜你想要日期没有一个时间组件。一种简单的方法是在 FROM 子句中将其作为单独的“变量”删除:

select sum(case when CreatedOn >= DATEADD(DAY, -7, v.date) and state = 0
                then 1 else 0
           end) as TckOpenLast7,
       sum(case when CreatedOn >= DATEADD(DAY, -15, v.date) and state = 0
                then 1 else 0
           end) as TckOpenLast15,
       . . .
from Incident i cross join
     (values (convert(date, getdate()))) v(date)
where CustomerId = @Accid;

【讨论】:

【参考方案2】:

你可以使用条件聚合

select
  sum(iif(CreatedOn >= DATEADD(DAY, -7, GETDATE()) And statecode=0, 1, 0) TckOpenLast7,
  sum(iif(CreatedOn >= DATEADD(DAY, -15, GETDATE() )And statecode=0, 1, 0) TckOpenLast15,
  sum(iif(CreatedOn >= DATEADD(DAY, -30, GETDATE()) And statecode=0, 1, 0) TckOpenLast30,
  sum(iif(CreatedOn >= DATEADD(DAY, -7, GETDATE()) And statecode=1, 1, 0) TckClosedLast7,
  sum(iif(CreatedOn >= DATEADD(DAY, -15, GETDATE()) And statecode=1, 1, 0) TckClosedLast15,
  sum(iif(CreatedOn >= DATEADD(DAY, -30, GETDATE()) And statecode=1, 1, 0) TckClosedLast30,
  sum(iif(CreatedOn >= DATEADD(DAY, -7, GETDATE()) And statecode=1, 1, 0) TckInProcessLast7,
  sum(iif(CreatedOn >= DATEADD(DAY, -15, GETDATE()) And statecode=1, 1, 0) TckInProcessLast15,
  sum(iif(CreatedOn >= DATEADD(DAY, -30, GETDATE()) And statecode=1, 1, 0) TckInProcessLast30
from Incident
where CustomerId=@Accid;

【讨论】:

以上是关于为不同时间段的每个相关记录计算 db 中的行数的主要内容,如果未能解决你的问题,请参考以下文章

计算由 UTL_FILE 创建的文件中的行数

根据另一个表中的条件计算表中的行数

对于 r2bc 中的 where 子句,我们是不是可以简写方式来计算 db 中存在的行数

在 TSQL 中,如何添加一个计数列来计算查询中的行数?

Laravel Eloquent 播种机计算每个外键的行数

Mongoose 中字段的每个不同值的行数