月季年度不同期間的業務資料查詢結果合併

2021-09-25 13:49:48 字數 3441 閱讀 1289

業務系統中經常需要統計不同期間的業務資料,以銷售收入統計為例,業務主管可能需要在一張**中同時顯示截止到某乙個日期(往往就是當前日期)的當日合計、月度合計、季度合計、年度累計,如下表:

統計日期

產品當日收入

月度收入

季度收入

年度收入

2019-5-25

產品001

1002000

30000

400000

2019-5-25

產品002

2002100

28000

350000

如果使用程式語言,統計不同時間段的合計,在邏輯上很簡單,只是工作量和程式效能問題。如果想在乙個查詢語句中同時輸出這些不同時間段的合計數,就沒那麼簡單了。

下面以乙個虛擬的【業務收入】表為例,介紹這個統計查詢的實現思路。該錶的結構如下圖:

因為是帶條件的查詢,所以首先需要定義乙個【統計日期】的變數,並賦值,比如:

declare @d date

set @d='2019-5-25' -- 或者 set @d=getdate() 設定當期系統日期為統計截止日期

然後,分別查詢當日合計、月度合計、季度合計、年度合計。

當日合計的sql如下:

select  日期,產品

,sum(收入) 當日收入

from 業務收入

where 1=1

and 日期 = @d

group by  日期,產品

月度合計的sql很類似,只是在where條件中有區別:

select  @d 日期,產品 -- 此處將 @d 輸出為【日期】字段,是為了顯示統計日期

,sum(收入) 月度收入

from 業務收入

where 1=1

and 日期 <= @d

and 日期 >= convert(datetime,convert(char(8),@d, 120)+'1') -- 這是取月初1號的日期

group by  產品

季度合計與此類似,只是起始日期條件有變化:

select  @d 日期,產品

,sum(收入) 季度收入

from 業務收入

where 1=1

and 日期 <= @d

and 日期 >= dateadd(quarter, datediff(quarter,0, @d),0) -- 這是取季度首日的日期

group by  產品

同樣的,年度合計是從年初1月1日開始,至統計截止日期:

select  @d 日期,產品

,sum(收入) 年度收入

from 業務收入

where 1=1

and 日期 <= @d

and 日期 >= convert(datetime,convert(char(4),@d, 120)+'-1-1') -- 這是取年初1月1日的日期

group by  產品

直接執行上面的這些sql語句,得到的查詢結果將是4個分離的結果集,如下圖:

為了合併這4個結果集,首先將每個資料集都新增幾個null欄位,然後使用union all將它們合併起來。

比如,對於當日收入,新增3個null欄位,分別是月度收入、季度收入、年度收入,sql語句變成:

select  日期,產品

,sum(收入) 當日收入

,null 月度收入 -- 新增null欄位

,null 季度收入 -- 新增null欄位

,null 年度收入 -- 新增null欄位

from 業務收入

where 1=1

and 日期 = @d

group by  日期,產品

其他3個sql語句採用類似方法,使得4個sql語句都輸出4個統計週期的合計收入,如下圖:

使用union all將4個sql語句合併,然後再按日期、產品進行彙總,最終的sql語句如下:

declare @d date

set @d='2019-5-25'

select 日期,產品

,sum(當日收入) 當日收入

,sum(月度收入) 月度收入

,sum(季度收入) 季度收入

,sum(年度收入) 年度收入

from

(select

日期,產品

,sum(收入) 當日收入

,null 月度收入

,null 季度收入

,null 年度收入

from 業務收入

where 1=1

and 日期 = @d

group by  日期,產品

union all

select

@d 日期,產品

,null 當日收入

,sum(收入) 月度收入

,null 季度收入

,null 年度收入

from 業務收入

where 1=1

and 日期 <= @d

and 日期 >= convert(datetime,convert(char(8),@d, 120)+'1')

group by  產品

union all

select

@d 日期,產品

,null 當日收入

,null 月度收入

,sum(收入) 季度收入

,null 年度收入

from 業務收入

where 1=1

and 日期 <= @d

and 日期 >= dateadd(quarter, datediff(quarter,0, @d),0)

group by  產品

union all

select

@d 日期,產品

,null 當日收入

,null 月度收入

,null 季度收入

,sum(收入) 年度收入

from 業務收入

where 1=1

and 日期 <= @d

and 日期 >= convert(datetime,convert(char(4),@d, 120)+'-1-1')

group by  產品

) vgroup by

日期,產品

執行這個sql語句,最終結果如下:

這個結果,正是期待的結果集形式。

月季流水賬

最近比較忙,好久沒有博了,先花幾天把我部落格周圍的荒草拔掉先.然後嘮叨嘮叨最近兩個月來印象比較深的值得一記的東西和想法。0.先詳細地談談工作 3 damn f u c k why程式除錯not通過?此處省去5千萬字 總之,這是有成效的乙個月,成功的乙個月,勝利的乙個月,在 的指引下,我們的工作取得了...

月季流水賬

最近比較忙,好久沒有博了,先花幾天把我部落格周圍的荒草拔掉先.然後嘮叨嘮叨最近兩個月來印象比較深的值得一記的東西和想法。0.先詳細地談談工作 3 damn f u c k why程式除錯not通過?此處省去5千萬字 總之,這是有成效的乙個月,成功的乙個月,勝利的乙個月,在 的指引下,我們的工作取得了...

C 自然周,月,季度計算。

判斷時間是否和伺服器時間是一天 public static bool judgetimeistoday datetime cs 計算當前季度多少天 public static intdatediff 計算當前月有多少天 public static intgetmonthdays 計算本週的周一日期 ...