为不同时间段的每个相关记录计算 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 中的行数的主要内容,如果未能解决你的问题,请参考以下文章