原公司用的資料庫是Oracle和MySQL居多,寫的SQL語句也比較少,有些生疏了。現在的公司使用的DB2資料庫,完全沒接觸過,導致一些函數的使用要在網上搜索案例,現在總結一點DB2的函數使用方法。 正確需求:查詢出指定日期的工作日,頁面傳一個天數,並返回一個新的日期。 下麵是時間表欄位: 剛開始項 ...
原公司用的資料庫是Oracle和MySQL居多,寫的SQL語句也比較少,有些生疏了。現在的公司使用的DB2資料庫,完全沒接觸過,導致一些函數的使用要在網上搜索案例,現在總結一點DB2的函數使用方法。
正確需求:查詢出指定日期的工作日,頁面傳一個天數,並返回一個新的日期。
下麵是時間表欄位:
表名 | 欄位 | 中文說明 | 備註 |
---|---|---|---|
ZCALDER | MANDT | 客戶端 | 判斷登陸的系統是否為測試系統 |
LANG | 語言 | 判斷語言 | |
YR | 年份 | ||
MTH | 月 | ||
ZDAY | 日 | ||
ZDATE | 日期 | ||
ZDAYS | 星期 | 周日是1,周六是7,周一至周五是2至6 | |
OFF_SRT | 自定休假區分 | 是否放假,上班N,放假Y | |
HLDY_YN | 公休日有無 | ||
YR_WEEK | 年份 | ||
WEEK_NO | 周次 | ||
CAL_RMK | 備註 |
剛開始項目需求說的不是很清楚,導致查詢的結果不對,原來的需求只是說過濾掉周六周日休息時間和周一至周五存調休放假的時間,得到上班的時間。
下麵的SQL語句查出的是系統當前時間和一個指定日期這個區間的上班記錄,SQL函數說明:
- CURRENT DATE:獲取系統當前日期,但是獲取的日期有 - 連接即:2017-11-30,資料庫中的日期存儲分為年月日三個欄位,且為字元型,這裡就需要用到相關函數對日期進行格式化。
- char(replace(char(date,iso),’-‘,”),8):轉成字元yyyymmdd格式,將結果中的短橫去掉後轉換成8位的字元。
- DECIMAL():也可以去掉 - 轉換成yyyymmdd格式
以上函數可以參考此帖:http://bbs.csdn.net/topics/310260682
select * from SAPHEC.ZCALDER a where (a.MANDT='720' and a.LANG='zh' --and a.YR='2017' --and a.mth='09' and a.ZDAYS!='1' and a.ZDAYS!='7' and a.off_srt!='Y' AND A.YR||A.MTH||A.ZDAY BETWEEN char(replace(char(CURRENT DATE,iso),'-',''),8) AND '20180101') union all (select * from SAPHEC.ZCALDER a where a.OFF_SRT='N' and a.LANG='zh' --and a.YR='2017' and a.MANDT='720' -- and a.mth='09' AND A.YR||A.MTH||A.ZDAY BETWEEN char(replace(char(CURRENT DATE,iso),'-',''),8) AND '20180101');
根據正確需求,返回一個日期,正確的SQL語句如下:
- rownumber() over():對重覆的欄位進行分組(類似group by),並生成一個序列
select DATE from (select DATE, ZDAYS, OFF_SRT, rownumber() over() as row_count from( --查詢出2017年之後周末上班的數據 select YR||MTH||ZDAY AS DATE, ZDAYS, OFF_SRT from saphec.ZCALDER where MANDT='720' and LANG='zh' AND YR||MTH||ZDAY > '20170101' and OFF_SRT = 'N' and (ZDAYS = '1' OR ZDAYS = '7') union --查詢出2017年之後的上班日,不包含周六周日 select YR||MTH||ZDAY AS DATE, ZDAYS, OFF_SRT from saphec.ZCALDER where MANDT='720' and LANG='zh' AND YR||MTH||ZDAY > '20170101' and OFF_SRT <> 'Y' AND ZDAYS IN ('2','3','4','5','6')) order by DATE fetch first 30 rows only) where row_count = 30;