解决一条高难度的,关于时间段 数据汇总问题
假設(shè)有如下兩張表:
表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的時(shí)間段內(nèi),每天都會(huì)有30數(shù)量的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沒(méi)有關(guān)系,現(xiàn)在要根據(jù)某一時(shí)間段,查詢剩余數(shù),比如:2007-5-11到2007-5-14的結(jié)余數(shù)量:
得到余下結(jié)果:
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是根據(jù)條件動(dòng)態(tài)生成。。。。
怎么比較高效的實(shí)現(xiàn)上述功能。。。我想到的需要循環(huán)好幾次,實(shí)在是夠理想,請(qǐng)朋友們一起想想,或者,通過(guò)修改表結(jié)構(gòu),達(dá)到相同的目的
解決方法:
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?????--開(kāi)始日期
DECLARE?@EndDate?smalldatetime??????--結(jié)束日期
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)?--構(gòu)造臨時(shí)表,用于分類統(tǒng)計(jì),和構(gòu)造行列轉(zhuǎn)換語(yǔ)句
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'
--沒(méi)有行列轉(zhuǎn)換前統(tǒng)計(jì),插入表#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
*/
以上方法沒(méi)有使用到游標(biāo),只是使用到2張臨時(shí)表就可以拷定,其實(shí)也可以使用1個(gè)臨時(shí)表就可以,只不過(guò)為了方便更好的了解計(jì)算方法,把分類統(tǒng)計(jì)過(guò)程獨(dú)立出來(lái)。
這方法雖然語(yǔ)句有點(diǎn)長(zhǎng)吧,但我相信比使用游標(biāo)更快。
問(wèn)題來(lái)源:http://community.csdn.net/Expert/topic/5532/5532084.xml?temp=.7621729
總結(jié)
以上是生活随笔為你收集整理的解决一条高难度的,关于时间段 数据汇总问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: KN-S1008S1016S1024S1
- 下一篇: 艰难的原创——谈互联网创业