解决一条高难度的,关于时间段 数据汇总问题
假設有如下兩張表:
表A:
id??? type??? begin_date?? end_date? count
---------------------------------------------
1???? A????? 2007-5-12???? 2007-5-14?? 30
2???? A????? 2007-5-11???? 2007-5-13?? 20
3???? B????? 2007-5-12???? 2007-5-15?? 50
4???? B????? 2007-5-13???? 2007-5-14?? 30
表示 從begin_date到end_date的時間段內,每天都會有30數量的A,其它行都是相同的意思
表B:(消耗表)
id?? type?? use_date? count
------------------------------
1??? A????? 2007-5-11? 15
2??? A????? 2007-5-12? 15
3??? B????? 2007-5-12? 20
4??? B????? 2007-5-13? 30
表A和表B的id沒有關系,現在要根據某一時間段,查詢剩余數,比如:2007-5-11到2007-5-14的結余數量:
得到余下結果:
id type 2007-5-11? 2007-5-12? 2007-5-13 2007-5-14
1? A????? 5????????? 35???????? 50???????? 30
2? B????? 0????????? 30???????? 50???????? 80
其中2007-5-12,5-13,5-14是根據條件動態生成。。。。
怎么比較高效的實現上述功能。。。我想到的需要循環好幾次,實在是夠理想,請朋友們一起想想,或者,通過修改表結構,達到相同的目的
解決方法:
insert?TableA?select?1?,'A',?'2007-5-12',?'2007-5-14',?30
union?all?select?2?,'A',?'2007-5-11',?'2007-5-13',?20
union?all?select?3?,'B',?'2007-5-12',?'2007-5-15',?50
union?all?select?4?,'B',?'2007-5-13',?'2007-5-14',?30
go
create?table?TableB(id?int,?type?char(1),?use_date?smalldatetime,?[count]?int)
insert?TableB?select?1?,'A',?'2007-5-11',?15
union?all?select?2?,'A',?'2007-5-12',?15
union?all?select?3?,'B',?'2007-5-12',?20
union?all?select?4?,'B',?'2007-5-13',?30
go
DECLARE?@BeginDate?smalldatetime?????--開始日期
DECLARE?@EndDate?smalldatetime??????--結束日期
DECLARE?@TmpDate?smalldatetime
DECLARE?@EXECUTE_SQL?nvarchar(4000)????????--
SELECT?@BeginDate='2007-5-11'
????,@EndDate='2007-5-14'
????,@TmpDate=@BeginDate
????,@EXECUTE_SQL='SELECT?type'
CREATE?TABLE?#T(TDate?smalldatetime)?--構造臨時表,用于分類統計,和構造行列轉換語句
WHILE?@TmpDate<=@EndDate
????BEGIN
????????INSERT?INTO?#T?SELECT?@TmpDate
????????SELECT?@EXECUTE_SQL=@EXECUTE_SQL+',SUM(CASE?TDATE?WHEN?'''+CONVERT(nchar(10),@TmpDate,120)+'''?THEN?[count]?ELSE?0?END)?AS?['+CONVERT(nchar(10),@TmpDate,120)+']'
????????????,@TmpDate=DATEADD(day,1,@TmpDate)
????????
????END
SET?@EXECUTE_SQL=@EXECUTE_SQL+CHAR(10)+'FROM?#T1?GROUP?BY?type'
--沒有行列轉換前統計,插入表#T1
SELECT?type,TDate,SUM([count])?AS?[count]?INTO?#T1
????FROM?(
????????SELECT?type,TDate,[count]?FROM?TableA?CROSS?JOIN?#T?WHERE?(begin_date?BETWEEN??@BeginDate?AND?@EndDate
????????????OR??end_date?BETWEEN??@BeginDate?AND?@EndDate)
????????????AND?TDate?BETWEEN?begin_date?AND?end_date
????????UNION?ALL?SELECT?type,use_date,-[count]?FROM?TableB?WHERE?use_date?BETWEEN??@BeginDate?AND?@EndDate
????????)?AS?A
????GROUP?BY?type,TDate
????ORDER?BY?type,TDate
EXECUTE(?@EXECUTE_SQL)????????
DROP?TABLE?TableA,TableB,#T,#T1
go
/**//*
type????2007-05-11????2007-05-12????2007-05-13????2007-05-14
---------------------------------------------------------------------------
A????????5????35????????50????????30
B????????0????30????????50????????80
*/
以上方法沒有使用到游標,只是使用到2張臨時表就可以拷定,其實也可以使用1個臨時表就可以,只不過為了方便更好的了解計算方法,把分類統計過程獨立出來。
這方法雖然語句有點長吧,但我相信比使用游標更快。
問題來源:http://community.csdn.net/Expert/topic/5532/5532084.xml?temp=.7621729
總結
以上是生活随笔為你收集整理的解决一条高难度的,关于时间段 数据汇总问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: KN-S1008S1016S1024S1
- 下一篇: 艰难的原创——谈互联网创业