按标志检索时间相关数据统计信息(计数),按外部 ID 分割,跨多个表,在一个数据集中返回

发布于 2024-10-20 19:48:02 字数 2189 浏览 1 评论 0原文

我有一个按 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 划分的所有内容。 QueueXTTodayCount 是今天发生的状态为 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 和一个查询来提取该视图以按日期范围进行选择,然后在代码中适当的地方对金额进行求和。

我只是有一种感觉,我让事情变得比我需要的更加复杂。一定有更好的方法。

I have a table of items that are split on a siteId and a status.

CREATE TABLE ItemDetail (
    ItemNumber    long,
    SiteId        int,
    Status        int,
    Created       datetime
)

And then I also have a user's table

CREATE TABLE UserDetail (
    UserId        int,
    Suspended     int
)

Status has 7 possible values (0-6) representing different queues. Let's call this variable x. Suspended, should only have 0 (active) or 1 (suspended). (don't ask me why it's an int, I didn't build it). Data is shown per site in a configurable time frame. Default is 5 days back. Let's call this variable a. I want to return, in one call, a dataset like this:

ActiveUserCount        int
SuspendedUserCount     int,
Queue0Count            int,
Queue0TodayCount       int,
Queue1Count            int,
Queue1TodayCount       int,
...

Where QueueXCount is everything in the last a days by status and siteid. QueueXTodayCount is everything with status x that happened today. So far, I have started a sproc like this

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

As if that isn't complicated enough, I am using Fluent Nhibernate. I'm not against using a sproc if I have to, but I have considered creating a view with the counts by day, pulling that in using nhibernate and a query to pick by date range, and then summing the amounts where appropriate in code.

I just have a feeling I am making this more complicated than I have to. There must be a better way.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

微暖i 2024-10-27 19:48:02

也许你可以用这个。

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

Perhaps you can use this.

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
终陌 2024-10-27 19:48:02

我使用 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

,然后获取所有数据并在模型中填充一个复合对象,该对象保存多个表的统计信息。

I created a view using CTE and a pivot

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

And then I get all my data and populate a composite object in my model that holds the statistics across multiple tables.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文