儲存過程,按時間間隔將多個表分組到新表:每日執行計劃
目前正在寫一篇論文,我的任務是將數據聚合到一個新表中
我正在嘗試建構一個聚合表,我將在其中按日期和時間間隔(比如 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
這是易熔的嗎?
您需要一個計數表(也稱為數字表)才能開始。這些有很多用途,可以很容易地用於生成您需要的間隔。
這個想法是生成與一天中的間隔相對應的數字序列。您可以將其與日期表交叉連接,以獲得所有關注日期的完整間隔集,從而獲得每個可能的間隔。
使用該結果集,您可以像往常一樣加入源數據並聚合。如果您只想要源數據中存在的間隔,則可以進行內連接,或者可以外連接來獲取所有間隔。請注意,我使用生成數字的惰性方式(遞歸 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
我留給你一個小提琴來展示。