按标志检索与时间相关的数据统计(计数),按外部 id 拆分,跨多个表,在一个数据集中返回
Posted
技术标签:
【中文标题】按标志检索与时间相关的数据统计(计数),按外部 id 拆分,跨多个表,在一个数据集中返回【英文标题】:Retrieving Time Dependent Data Statistics (counts) by flag, split on foreign id, across multiple tables, returned in one dataset 【发布时间】:2011-03-07 15:23:21 【问题描述】:我有一个按 siteId 和状态拆分的项目表。
CREATE TABLE ItemDetail (
ItemNumber long,
SiteId int,
Status int,
Created datetime
)
然后我还有一个用户表
CREATE TABLE UserDetail (
UserId int,
Suspended int
)
Status 有 7 个可能的值 (0-6) 代表不同的队列。我们称这个变量为 x。暂停,应该只有 0(活动)或 1(暂停)。 (不要问我为什么它是一个 int,我没有构建它)。数据在可配置的时间范围内按站点显示。默认为 5 天前。我们称这个变量为 a。我想在一次调用中返回这样的数据集:
ActiveUserCount int
SuspendedUserCount int,
Queue0Count int,
Queue0TodayCount int,
Queue1Count int,
Queue1TodayCount int,
...
其中 QueueXCount 是过去几天按状态和站点 ID 划分的所有内容。 QueueXTodayCount 是今天发生的所有状态为 x 的事件。到目前为止,我已经开始了这样的存储过程
CREATE PROCEDURE GetSiteStatistics
@SiteId int,
@Window int
AS
BEGIN
DECLARE @Today datetime
DECLARE @Tomorrow datetime
DECLARE @CutOff datetime
SET @Today = (CAST(YEAR(getdate()) as varchar) +
RIGHT('00' + CAST(MONTH(getdate()) as varchar), 2) +
RIGHT('00' + CAST(DAY(getdate()) as varchar), 2))
SET @Tomorrow = DATEADD(dd, 1, @Today)
SET @CutOff = DATEADD(dd, @Window + 1, @Today)
DECLARE
@SuspendedUserCount int,
@ActiveUserCount int,
@Queue0Count int,
@Queue0TodayCount int,
...
SELECT @SuspendedUserCount = count(UserId) FROM UserDetail WHERE Suspended = 1 AND SiteId = @SiteId
SELECT @ActiveUserCount = count(UserId) FROM UserDetail WHERE Suspended = 0 AND SiteId = @SiteId
SELECT @Queue0Count = count(ItemNumber) FROM ItemDetail WHERE Status = 0 AND SiteId = @SiteId AND Created >= @Today AND Created < @CutOff
SELECT @Queue0TodayCount = count(ItemNumber) FROM ItemDetail WHERE Status = 0 AND SiteId = @SiteId AND Created >= @Today AND Created < @Tomorrow
...
SELECT @SuspendedUserCount AS SuspendedUsers, @ActiveUserCount AS ActiveUsers, @Queue0Count AS Queue0, @Queue0TodayCount AS @Queue0Today...
END
好像这还不够复杂,我正在使用 Fluent Nhibernate。如果必须,我不反对使用存储过程,但我考虑过创建一个按天计数的视图,使用 nhibernate 和一个查询来按日期范围选择,然后在代码中适当地对数量求和。
我只是觉得我让这件事变得比我必须做的更复杂。一定有更好的办法。
【问题讨论】:
【参考方案1】:也许你可以用这个。
declare @SiteId int = 1
declare @Window int = 5
declare @ToDay datetime = dateadd(d, datediff(d, 0, getdate()), 0)
declare @CutOff datetime = dateadd(d, @Window, @ToDay)
declare @Tomorrow datetime = dateadd(d, 1, @ToDay)
select * from
(
select
sum(case when Suspended = 0 then 1 else 0 end) as ActiveUserCount,
sum(case when Suspended = 1 then 1 else 0 end) as SuspendedUserCount
from UserDetail
where
SiteId = @SiteId
) as q1 cross join
(
select
sum(case when Status = 0 then 1 else 0 end) as Queue0Count,
sum(case when Status = 1 then 1 else 0 end) as Queue1Count,
sum(case when Status = 2 then 1 else 0 end) as Queue2Count,
sum(case when Status = 3 then 1 else 0 end) as Queue3Count,
sum(case when Status = 4 then 1 else 0 end) as Queue4Count,
sum(case when Status = 5 then 1 else 0 end) as Queue5Count,
sum(case when Status = 6 then 1 else 0 end) as Queue6Count,
sum(case when Status = 0 and Created < @Tomorrow then 1 else 0 end) as Queue0TodayCount,
sum(case when Status = 1 and Created < @Tomorrow then 1 else 0 end) as Queue1TodayCount,
sum(case when Status = 2 and Created < @Tomorrow then 1 else 0 end) as Queue2TodayCount,
sum(case when Status = 3 and Created < @Tomorrow then 1 else 0 end) as Queue3TodayCount,
sum(case when Status = 4 and Created < @Tomorrow then 1 else 0 end) as Queue4TodayCount,
sum(case when Status = 5 and Created < @Tomorrow then 1 else 0 end) as Queue5TodayCount,
sum(case when Status = 6 and Created < @Tomorrow then 1 else 0 end) as Queue6TodayCount
from ItemDetail
where
Created >= @ToDay and
Created < @CutOff
) as q2
【讨论】:
【参考方案2】:我使用 CTE 和枢轴创建了一个视图
CREATE VIEW [dbo].[SiteQueueDailyStatistics]
AS
WITH statCTE AS (
SELECT
Count(ItemNumber)as ItemCount,
SiteId,
Status,
DATEADD(dd, 0, DATEDIFF(dd, 0, ScanDate)) AS ScanDay
FROM
ItemDetail
group by SiteId, Status, DATEADD(dd, 0, DATEDIFF(dd, 0, ScanDate))
)
SELECT
SiteId,
ScanDay,
ISNULL([0], 0) AS Queue0,
ISNULL([1], 0) AS Queue1,
ISNULL([2], 0) AS Queue2,
ISNULL([3], 0) AS Queue3,
ISNULL([4], 0) AS Queue4,
ISNULL([5], 0) AS Queue5,
ISNULL([6], 0) AS Queue6
FROM
statCTE
PIVOT
(
SUM(ItemCount)
FOR [Status] IN ([0], [1], [2], [3], [4], [5], [6])
)
AS p
GO
然后我获取所有数据并在我的模型中填充一个复合对象,该对象包含多个表的统计信息。
【讨论】:
以上是关于按标志检索与时间相关的数据统计(计数),按外部 id 拆分,跨多个表,在一个数据集中返回的主要内容,如果未能解决你的问题,请参考以下文章
具有特定条件计数的 Mongodb 聚合并按输出投影的日期范围过滤不能按预期工作