原公司用的是oracle和mysql居多,写的sql语句也比较少,有些生疏了。现在的公司使用的db2数据库,完全没接触过,导致一些函数的使用要在网上搜索案例,现在总结一点db2的函数使用方法。
正确需求:查询出指定日期的工作日,页面传一个天数,并返回一个新的日期。
下面是时间表字段:
字段 | 中文说明 | 备注 |
---|---|---|
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格式
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;