Sql-Server

儲存過程,按時間間隔將多個表分組到新表:每日執行計劃

  • March 18, 2021

目前正在寫一篇論文,我的任務是將數據聚合到一個新表中

我正在嘗試建構一個聚合表,我將在其中按日期和時間間隔(比如 30 分鐘)儲存每個行組。

我遇到了商店程序,並認為這將是最好的解決方案。

我的源表構造如下(StartDateTime = datetime2)(

StartDateTime           Name    ...   Path         
2021-02-28 20:23:43.1   Tom     ...   FG_T
2021-02-28 20:24:34.6   Tom     ...   LS_t
---                    ---     ...   ---
2021-02-28 20:35:09.5   Abby    ...   FS_t
2021-02-28 21:55:34.6   Tom     ...   FS_t
2021-XX-XX HH:MM:SS.s   Abby     ...  XX

我的願望是有一個輸出表(必須是一個我想隨時間儲存它的表,而不僅僅是臨時表),它計算給定時間段內發生的事件數量,這個過程應該每天執行一次並創建一個條目對於過去 24 小時內的每個可用“時間段”。

PeriodStart              Period(sek)    Name     Sum
2021-02-28 20:00:00.0    1800           Tom      2
2021-02-28 20:30:00.0    1800           Abby     1
2021-02-28 21:00:00.0    1800           NULL     NULL
2021-02-28 21:30:00.0    1800           Tom      1

有人能指出我在哪裡可以找到有關創建這樣的東西的資訊的正確方向嗎?

我先感謝一位有抱負的 SQL 愛好者 :)

更新1:

正如@SMor 的回答所示,我正在尋求使用某種計數表來生成時隙。

當我查看他提供的程式碼時,我意識到我忘記了一些我想解決的限制

澄清我想要的結果和目前表格的結構:

此任務旨在匯總通過一組給定埠(中繼)進入的幾個連接,新創建的表(在此過程中形成的表)稍後將用作相應視圖的掛鉤點,該視圖將在SSRS。

我的目標是計算每個中繼在給定時隙內的傳入連接數(因此也按中繼分組)。一旦我完成了第一部分,也非常希望在給定的插槽內同時查看最大連接數。(如 MaxConnectionAtOnce )

表:RAW_DATA

我試圖將它添加到儲存過程中,我在所做的修改周圍添加了塊註釋( /* */ )。

CREATE OR ALTER PROCEDURE [schemma].[TrunkSummery]
@date datetime2(7),
@period int
AS
BEGIN
   -- Creat timeslotable
       with numbers(val) as 
           (select 1 union all select val + 1 from numbers where val < 48)
       select @date, nbr.val, 
          dateadd(minute, (nbr.val - 1) * 30, @date) as period_start, 
          dateadd(minute, (nbr.val    ) * 30, @date) as period_end 
       from numbers as nbr 
       order by nbr.val;

       with numbers(val) as 
           (select 1 union all select val + 1 from numbers where val < 48),
       periods as (
           select @date as [date], nbr.val, 
          dateadd(minute, (nbr.val - 1) * 30, @date) as period_start, 
          dateadd(minute, (nbr.val    ) * 30, @date) as period_end 
          from numbers as nbr)
       select pers.period_start, @period as Period, src.trunk, count(src.trunk) as 'all' 
       /*, count(maxAtOnce) */ 
       --from periods as pers left  join @raw_data as src 
       from periods as pers inner join HDO.RAW_DATA as src 
       on src.StartDateTime >= pers.period_start and src.StartDateTime < pers.period_end
       group by src.trunk, pers.period_start, pers.period_end
       order by pers.period_start, src.trunk,  pers.period_end
END
GO

EXECUTE [schemma].[TrunkSummery] @date = '20210224', @period = 30;
GO

根據我的嘗試,我認為我也需要在樹幹上進行分組/訂購。

--Current output
period_start                 Period   trunk     all
2021-02-24 20:00:00.0000000  30       T1        3
2021-02-24 20:30:00.0000000  30       T1        1
2021-02-24 20:30:00.0000000  30       T2        1
2021-02-24 22:30:00.0000000  30       T1        1
2021-02-24 22:30:00.0000000  30       T2        1


-- Desired
period_start                 Period   trunk     all    max
2021-02-24 20:00:00.0000000  30       T1        3      2
2021-02-24 20:30:00.0000000  30       T1        1      1
2021-02-24 22:30:00.0000000  30       T1        1      1
2021-02-24 20:30:00.0000000  30       T2        1      1
2021-02-24 22:30:00.0000000  30       T2        1      1

這是易熔的嗎?

基於@SMor 的小提琴和新表

您需要一個計數表(也稱為數字表)才能開始。這些有很多用途,可以很容易地用於生成您需要的間隔。

這個想法是生成與一天中的間隔相對應的數字序列。您可以將其與日期表交叉連接,以獲得所有關注日期的完整間隔集,從而獲得每個可能的間隔。

使用該結果集,您可以像往常一樣加入源數據並聚合。如果您只想要源數據中存在的間隔,則可以進行內連接,或者可以外連接來獲取所有間隔。請注意,我使用生成數字的惰性方式(遞歸 cte) - 但對於此要求,列表非常小。我也只考慮了在局部變數中設置的單個日期@date。因此,無需針對您的一組日期進行交叉連接。

with numbers(val) as 
   (select 1 union all select val + 1 from numbers where val < 48),
periods as (
   select @date as [date], nbr.val, 
  dateadd(minute, (nbr.val - 1) * 30, @date) as period_start, 
  dateadd(minute, (nbr.val    ) * 30, @date) as period_end 
  from numbers as nbr)
select pers.period_start, pers.period_end, src.name, count(src.name) as cnt 
--from periods as pers left  join @source as src 
from periods as pers inner join @source as src 
on src.startdt >= pers.period_start and src.startdt < pers.period_end
group by pers.period_start, pers.period_end, src.name
order by pers.period_start, pers.period_end, src.name

我留給你一個小提琴來展示。

引用自:https://dba.stackexchange.com/questions/287225