查看: 6085|回复: 12

【大话IT】如何找出下一个不是节假日的工作日

[复制链接]
论坛徽章:
13
2010新春纪念徽章
日期:2010-03-01 11:04:59技术图书徽章
日期:2018-03-01 10:21:49秀才
日期:2018-03-01 10:21:252015年新春福章
日期:2015-03-06 11:58:18喜羊羊
日期:2015-03-04 14:52:46优秀写手
日期:2014-04-22 06:00:18马上有对象
日期:2014-02-18 16:44:082014年新春福章
日期:2014-02-18 16:44:082013年新春福章
日期:2013-02-25 14:51:242012新春纪念徽章
日期:2012-01-04 11:56:01
发表于 2015-1-25 13:27 | 显示全部楼层 |阅读模式
想要找出下一个不是节假日的工作日
WITH HOLIDAY_TABLE AS
  (SELECT to_date('25-dec-2014','dd-mon-yyyy') hday FROM dual
  UNION ALL
  SELECT to_date('26-dec-2014','dd-mon-yyyy') FROM dual
  UNION ALL
  SELECT to_date('01-jan-2015','dd-mon-yyyy') FROM dual
  )
SELECT DT ,
  TO_CHAR(DT,'DY') DAY_OF_WEEK ,
  CASE
    WHEN TO_CHAR(DT,'dy') IN ('sat','sun')
    THEN 'WEEK_END'
    WHEN EXISTS
      (SELECT NULL FROM HOLIDAY_TABLE WHERE HDAY=DT
      )
    THEN 'HOLIDAY'
    ELSE 'WEEK_DAY'
  END AS DAY_IND
FROM
  (SELECT to_date('19-dec-2014','dd-mon-yyyy') + level -1 dt
  FROM DUAL
    CONNECT BY LEVEL<=20
  );

DT
DAY_OF_WEEK
day_ind
2014-DEC-19
FRI
WEEK_DAY
2014-DEC-20
SAT
WEEK_END
2014-DEC-21
SUN
WEEK_END
2014-DEC-22
MON
WEEK_DAY
2014-DEC-23
TUE
WEEK_DAY
2014-DEC-24
WED
WEEK_DAY
2014-DEC-25
THU
HOLIDAY
2014-DEC-26
FRI
HOLIDAY
2014-DEC-27
SAT
WEEK_END
2014-DEC-28
SUN
WEEK_END
2014-DEC-29
MON
WEEK_DAY
2014-DEC-30
TUE
WEEK_DAY
2014-DEC-31
WED
WEEK_DAY
2015-JAN-01
THU
HOLIDAY
2015-JAN-02
FRI
WEEK_DAY
2015-JAN-03
SAT
WEEK_END
2015-JAN-04
SUN
WEEK_END
2015-JAN-05
MON
WEEK_DAY
2015-JAN-06
TUE
WEEK_DAY
2015-JAN-07
WED
WEEK_DAY

想得到下面的结果:
DT
Next_business_day
day_ind
2014-DEC-19
2014-DEC-22
WEEK_DAY
2014-DEC-20
2014-DEC-22
WEEK_END
2014-DEC-21
2014-DEC-22
WEEK_END
2014-DEC-22
2014-DEC-23
WEEK_DAY
2014-DEC-23
2014-DEC-24
WEEK_DAY
2014-DEC-24
2014-DEC-29
WEEK_DAY
2014-DEC-25
2014-DEC-29
HOLIDAY
2014-DEC-26
2014-DEC-29
HOLIDAY
2014-DEC-27
2014-DEC-29
WEEK_END
2014-DEC-28
2014-DEC-29
WEEK_END
2014-DEC-29
2014-DEC-30
WEEK_DAY
2014-DEC-30
2014-DEC-31
WEEK_DAY
2014-DEC-31
2015-JAN-02
WEEK_DAY
2015-JAN-01
2015-JAN-02
HOLIDAY
2015-JAN-02
2015-JAN-05
WEEK_DAY
2015-JAN-03
2015-JAN-05
WEEK_END
2015-JAN-04
2015-JAN-05
WEEK_END
2015-JAN-05
2015-JAN-06
WEEK_DAY
2015-JAN-06
2015-JAN-07
WEEK_DAY
2015-JAN-07
2015-JAN-08
WEEK_DAY



论坛徽章:
126
ITPUB元老
日期:2007-07-04 17:27:50会员2007贡献徽章
日期:2007-09-26 18:42:10现任管理团队成员
日期:2011-05-07 01:45:08优秀写手
日期:2015-01-09 06:00:14版主7段
日期:2015-07-16 02:10:00
发表于 2015-1-25 14:46 来自手机 | 显示全部楼层
本帖最后由 bell6248 于 2015-1-25 16:41 编辑

如下:

select dt,
            last_value(case when day_ind in('WEEK_END', 'HOLIDAY') then null else dt end ignore nulls) over(order by dt desc) next_business_day,
          day_ind
   from (your_current_sql)
order by dt;



   


使用道具 举报

回复
论坛徽章:
13
2010新春纪念徽章
日期:2010-03-01 11:04:59技术图书徽章
日期:2018-03-01 10:21:49秀才
日期:2018-03-01 10:21:252015年新春福章
日期:2015-03-06 11:58:18喜羊羊
日期:2015-03-04 14:52:46优秀写手
日期:2014-04-22 06:00:18马上有对象
日期:2014-02-18 16:44:082014年新春福章
日期:2014-02-18 16:44:082013年新春福章
日期:2013-02-25 14:51:242012新春纪念徽章
日期:2012-01-04 11:56:01
 楼主| 发表于 2015-1-26 02:17 | 显示全部楼层
本帖最后由 KEN6503 于 2015-1-26 02:18 编辑
bell6248 发表于 2015-1-25 14:46
如下:

select dt,

谢谢你的回复。 这个结果好像有些问题。 只是节假日的next_business_day 是正确的。

14-Dec-19        14-Dec-19        WEEK_DAY
14-Dec-20        14-Dec-22        WEEK_END
14-Dec-21        14-Dec-22        WEEK_END

14-Dec-22        14-Dec-22        WEEK_DAY
14-Dec-23        14-Dec-23        WEEK_DAY
14-Dec-24        14-Dec-24        WEEK_DAY
14-Dec-25        14-Dec-29        HOLIDAY
14-Dec-26        14-Dec-29        HOLIDAY
14-Dec-27        14-Dec-29        WEEK_END
14-Dec-28        14-Dec-29        WEEK_END

14-Dec-29        14-Dec-29        WEEK_DAY
14-Dec-30        14-Dec-30        WEEK_DAY
14-Dec-31        14-Dec-31        WEEK_DAY
15-Jan-01        15-Jan-02        HOLIDAY
15-Jan-02        15-Jan-02        WEEK_DAY
15-Jan-03        15-Jan-05        WEEK_END
15-Jan-04        15-Jan-05        WEEK_END

15-Jan-05        15-Jan-05        WEEK_DAY
15-Jan-06        15-Jan-06        WEEK_DAY
15-Jan-07        15-Jan-07        WEEK_DAY

使用道具 举报

回复
论坛徽章:
401
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
发表于 2015-1-26 09:58 | 显示全部楼层
把节假日放在一个表,找day+1,2,3,...的第一个不存在的

使用道具 举报

回复
论坛徽章:
126
ITPUB元老
日期:2007-07-04 17:27:50会员2007贡献徽章
日期:2007-09-26 18:42:10现任管理团队成员
日期:2011-05-07 01:45:08优秀写手
日期:2015-01-09 06:00:14版主7段
日期:2015-07-16 02:10:00
发表于 2015-1-26 10:35 | 显示全部楼层
KEN6503 发表于 2015-1-26 02:17
谢谢你的回复。 这个结果好像有些问题。 只是节假日的next_business_day 是正确的。

14-Dec-19      ...





由于昨天没有环境测试, 今天刚刚看你的回复, 重写了, 你测试一下,代码如下:

SQL> select * from your_sql;

DT          DAY_OF_WEEK  DAY_IND
----------- ------------ --------
2014/12/19  星期五       WEEK_DAY
2014/12/20  星期六       WEEK_END
2014/12/21  星期日       WEEK_END
2014/12/22  星期一       WEEK_DAY
2014/12/23  星期二       WEEK_DAY
2014/12/24  星期三       WEEK_DAY
2014/12/25  星期四       HOLIDAY
2014/12/26  星期五       HOLIDAY
2014/12/27  星期六       WEEK_END
2014/12/28  星期日       WEEK_END
2014/12/29  星期一       WEEK_DAY
2014/12/30  星期二       WEEK_DAY
2014/12/31  星期三       WEEK_DAY
2015/1/1    星期四       HOLIDAY
2015/1/2    星期五       WEEK_DAY
2015/1/3    星期六       WEEK_END
2015/1/4    星期日       WEEK_END
2015/1/5    星期一       WEEK_DAY
2015/1/6    星期二       WEEK_DAY
2015/1/7    星期三       WEEK_DAY

20 rows selected

SQL>
SQL> select  dt,
  2          day_of_week,
  3          case
  4            when day_ind = 'WEEK_DAY' and lag(day_ind) over(order by dt desc) in('WEEK_END', 'HOLIDAY') then
  5                 lag(next_business_day) over(order by dt desc)
  6            else
  7                 next_business_day
  8          end next_business_day,
  9          day_ind
10  from
11  (select dt,
12          day_of_week,
13          case
14             when day_ind in('WEEK_END', 'HOLIDAY') then
15                  last_value(case when day_ind in('WEEK_END', 'HOLIDAY') then null else dt end ignore nulls) over(order by dt desc)
16          else
17                  dt + 1
18          end next_business_day,
19          day_ind
20      from your_sql)
21  order by dt;

DT          DAY_OF_WEEK  NEXT_BUSINESS_DAY DAY_IND
----------- ------------ ----------------- --------
2014/12/19  星期五       2014/12/22        WEEK_DAY
2014/12/20  星期六       2014/12/22        WEEK_END
2014/12/21  星期日       2014/12/22        WEEK_END
2014/12/22  星期一       2014/12/23        WEEK_DAY
2014/12/23  星期二       2014/12/24        WEEK_DAY
2014/12/24  星期三       2014/12/29        WEEK_DAY
2014/12/25  星期四       2014/12/29        HOLIDAY
2014/12/26  星期五       2014/12/29        HOLIDAY
2014/12/27  星期六       2014/12/29        WEEK_END
2014/12/28  星期日       2014/12/29        WEEK_END
2014/12/29  星期一       2014/12/30        WEEK_DAY
2014/12/30  星期二       2014/12/31        WEEK_DAY
2014/12/31  星期三       2015/1/2          WEEK_DAY
2015/1/1    星期四       2015/1/2          HOLIDAY
2015/1/2    星期五       2015/1/5          WEEK_DAY
2015/1/3    星期六       2015/1/5          WEEK_END
2015/1/4    星期日       2015/1/5          WEEK_END
2015/1/5    星期一       2015/1/6          WEEK_DAY
2015/1/6    星期二       2015/1/7          WEEK_DAY
2015/1/7    星期三       2015/1/8          WEEK_DAY

20 rows selected

SQL>




使用道具 举报

回复
论坛徽章:
35
ITPUB8周年纪念徽章
日期:2015-09-11 12:12:40慢羊羊
日期:2015-05-15 09:22:38慢羊羊
日期:2015-06-19 09:29:03双鱼座
日期:2015-07-16 13:16:54双子座
日期:2015-08-27 13:16:31射手座
日期:2015-08-28 13:15:55处女座
日期:2015-09-06 15:45:26金牛座
日期:2015-09-17 11:01:38金牛座
日期:2015-11-02 09:28:35双鱼座
日期:2015-12-24 15:20:14
发表于 2015-1-26 15:36 | 显示全部楼层
我是把非正常的节假日(周六日工作的,以及非周六日休息的)放一个表里面,然后自建个函数去查询。

使用道具 举报

回复
认证徽章
论坛徽章:
244
2015年新春福章
日期:2015-05-28 10:58:322015年新春福章
日期:2015-03-19 09:32:472015年新春福章
日期:2015-03-06 11:58:182015年新春福章
日期:2015-05-21 11:46:522015年新春福章
日期:2015-05-22 13:32:002015年新春福章
日期:2015-06-25 14:26:362015年新春福章
日期:2015-07-01 17:15:212015年新春福章
日期:2015-07-01 17:15:212015年新春福章
日期:2015-07-01 17:12:082015年新春福章
日期:2015-05-18 13:50:34
发表于 2015-1-26 17:49 | 显示全部楼层
select

dt, to_char(dt,'day','NLS_DATE_LANGUAGE=AMERICAN') week_day
, case when rtrim(to_char(dt,'day','NLS_DATE_LANGUAGE=AMERICAN'))  =  'friday'
then dt+3
when rtrim(to_char(dt,'day','NLS_DATE_LANGUAGE=AMERICAN'))  =  'saturday'
then dt+2
when rtrim(to_char(dt,'day','NLS_DATE_LANGUAGE=AMERICAN'))  =  'saturday'
then dt+1
else dt+1 end next_work_day

FROM
   (SELECT to_date('19-dec-2014','dd-mon-yyyy') + level -1 dt
   FROM DUAL
     CONNECT BY LEVEL<=20
   );
   
   

使用道具 举报

回复
论坛徽章:
13
2010新春纪念徽章
日期:2010-03-01 11:04:59技术图书徽章
日期:2018-03-01 10:21:49秀才
日期:2018-03-01 10:21:252015年新春福章
日期:2015-03-06 11:58:18喜羊羊
日期:2015-03-04 14:52:46优秀写手
日期:2014-04-22 06:00:18马上有对象
日期:2014-02-18 16:44:082014年新春福章
日期:2014-02-18 16:44:082013年新春福章
日期:2013-02-25 14:51:242012新春纪念徽章
日期:2012-01-04 11:56:01
 楼主| 发表于 2015-1-26 18:45 | 显示全部楼层
lcpp8 发表于 2015-1-26 15:36
我是把非正常的节假日(周六日工作的,以及非周六日休息的)放一个表里面,然后自建个函数去查询。

把函数贴上来参考一下

使用道具 举报

回复
论坛徽章:
126
ITPUB元老
日期:2007-07-04 17:27:50会员2007贡献徽章
日期:2007-09-26 18:42:10现任管理团队成员
日期:2011-05-07 01:45:08优秀写手
日期:2015-01-09 06:00:14版主7段
日期:2015-07-16 02:10:00
发表于 2015-1-26 19:39 来自手机 | 显示全部楼层
KEN6503 发表于 2015-1-26 18:45
把函数贴上来参考一下

5#已经提供了答案, 自己测试一下吧

使用道具 举报

回复
论坛徽章:
401
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
发表于 2015-1-27 00:31 | 显示全部楼层
KEN6503 发表于 2015-1-26 18:45
把函数贴上来参考一下

用函数查表大部分时候是不好的

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 
京ICP备09055130号-4  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表