標籤:
在BI報表開發時,經常需要計算同比環比,需要用到月末日期,用資料庫系統的日期函數操作需要在每處用到日期的地方都把函數寫一遍,在某些特殊情形,函數會很複雜,甚至不能實現想要的結果。
比如在Teradata中的Addmonths函數,只計算了月份:
日期 |
增量值 |
結果 |
2015/01/01 |
1 |
2015/02/01 |
2015/01/31 |
1 |
2015/02/28 |
2015/02/28 |
-1 |
2015/01/28 |
2015/03/31 |
-1 |
2015/02/28 |
2015/02/28 |
0 |
2015/02/28 |
如表格所示,遇到月末的時候,不能統計整月的資訊,常常不是想要的結果。
因此有必要在作業中加入變數,實現每月取月末的資料。
perl實現如下,簡單測試,生產環境上線前請使用sprintf格式化一下。
#!/usr/bin/perl# 擷取任意月份月末日期# Liangwl# 2015/9/18sub Add_Delta_Month{ my ($date,$cnt) = @_; my $year = int($date/10000); my $month = int($date/100)%100 + $cnt -1; my $yyyymm = ($year + floor($month/12)) * 100 + $month % 12 + 1; my @mmdd; push @mmdd,qw(0131),(int($yyyymm/100)%4==0?"0229":"0228"),qw(0331 0430 0531 0630 0731 0831 0930 1031 1130 1231); return int($yyyymm/100).$mmdd[($yyyymm%100-1)%12];} sub floor{ my ($i) = @_; return $i >= int($i) ? int($i) : int($i) - 1;} print Add_Delta_Month(20150131,-14)."\n";print Add_Delta_Month(20150131,-13)."\n";print Add_Delta_Month(20150131,-12)."\n";print Add_Delta_Month(20150131,0)."\n";print Add_Delta_Month(20150131,1)."\n";print Add_Delta_Month(20150131,11)."\n";print Add_Delta_Month(20150131,12)."\n";print Add_Delta_Month(20150131,13)."\n\n";
應用情境:"最近六個月統計資料","環比變化","同比變化","X季度同比"等等
PERL擷取前後任意月份月末