分享

盒子论坛 v2.1

 quasiceo 2017-05-06
标题:
SQL 中关于工作日的计算 浏览:410
加入我的收藏
楼主:     近日在一小项目中遇到需要计算今天之前(之后)若干工作日的问题,花数小时百度,均未搜到到满意答案,逐自行写了一个,颇感满意:
 CREATE TABLE [dbo]. [T_SYS_Holiday](
[id] [int] IDENTITY(1, 1) NOT NULL,
[name] [varchar](100) COLLATE Chinese_PRC_CI_AS NOT NULL,
[Hdate] [datetime] NOT NULL,
[isholiday] [varchar](20) COLLATE Chinese_PRC_CI_AS NOT NULL,
CONSTRAINT [PK_T_SYS_Holiday] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
)ON [PRIMARY]
GO

--2017年节假日数据
INSERT INTO T_SYS_Holiday
          (name,Hdate,isholiday)
 select '元旦补休','2017-01-02','节假日'
UNION select '春节补班','2017-01-22','非节假日'
UNION  select '春节休息','2017-01-27','节假日'
UNION select '春节休息','2017-01-30','节假日'
UNION select '春节休息','2017-01-31','节假日'
UNION select '春节休息','2017-02-01','节假日'
UNION select '春节休息','2017-02-02','节假日'
UNION select '春节补班','2017-02-04','非节假日'
UNION select '清明补班','2017-04-01','非节假日'
UNION select '清明','2017-04-03','节假日'
UNION select '清明','2017-04-04','节假日'
UNION select '五一','2017-05-01','节假日'
UNION select '端午补班','2017-05-27','非节假日'
UNION select '端午','2017-05-29','节假日'
UNION select '端午','2017-05-30','节假日'
UNION select '国庆补班','2017-09-30','非节假日'
UNION select '国庆','2017-10-02','节假日'
UNION select '国庆','2017-10-03','节假日'
UNION select '国庆','2017-10-04','节假日'
UNION select '国庆','2017-10-05','节假日'
UNION select '国庆','2017-10-06','节假日'

---计算几天前的工作日
create function dbo.GetPreWorkDay
(@date0 datetime,
 @x int)
returns datetime
as
begin
 declare @i int,@date1 datetime
 select @i=1,@date1=@date0
 while(@i<=@x)
 begin
  select @date1=dateadd(d,-1,@date1)
  if datepart(dw,@date1) not in(1,7)
  begin
    select @i=@i+1
  end
   if exists (select HDate from t_sys_holiday where isholiday='节假日' and @date1>= HDate and @date1<HDate +1)
  begin
    select @i=@i-1
  end
  if exists (select HDate from t_sys_holiday where isholiday='非节假日' and @date1>= HDate and @date1<HDate +1)
  begin
    select @i=@i+1
  end
 end
 return @date1
end
Go
---计算几天后的工作日
create function dbo.GetNextWorkDay
(@date0 datetime,
 @x int)
returns datetime
as
begin
 declare @i int,@date1 datetime
 select @i=1,@date1=@date0
 while(@i<=@x)
 begin
  select @date1=dateadd(d,1,@date1)
  if datepart(dw,@date1) not in(1,7)
  begin
    select @i=@i+1
  end
  if exists (select HDate from t_sys_holiday where isholiday='节假日' and @date1>= HDate and @date1<HDate +1)
  begin
    select @i=@i-1
  end
  if exists (select HDate from t_sys_holiday where isholiday='非节假日' and @date1>= HDate and @date1<HDate +1)
  begin
    select @i=@i+1
  end
 end
 return @date1
end

Go

--select dbo.GetNextWorkDay('2017-01-20',7)
--select dbo.GetPreWorkDay('2017-02-4',7)

--select dbo.GetNextWorkDay('2017-04-20',7)
--select dbo.GetPreWorkDay('2017-05-2',7)

若有不当之处,望大伙指正。
----------------------------------------------
-
作者:
男 beibeili (beibeili) ▲▲▲▲△ -
注册会员
2017-5-2 8:33:36
1楼: 建议不要这样硬编码!
你的代码2017年是有效的,那么2018年呢?难道再改一次代码?
建议创建一个字典表用来记录每年的节假日信息,这样不但好维护,而且不必使用那一堆Union,效率会高很多的
----------------------------------------------
-
作者:
男 beibeili (beibeili) ▲▲▲▲△ -
注册会员
2017-5-2 11:52:58
2楼: 不好意思,没有看清楚,您是创建了字典表!
:(
----------------------------------------------
-
作者:
男 star5 (星五) ▲▲▲▲▲ -
盒子活跃会员
2017-5-2 13:06:51
3楼: 感谢楼主分享!
----------------------------------------------
博客 - http://
作者:
男 luwakin (luwakin) ▲▲▲△△ -
注册会员
2017-5-2 21:15:14
4楼: 每年的节假日又不一定,只能硬编码吧。
但是可以写个小程序直接去日历网站抓数据,反正也就一年抓一次就可以了
直接抓一年每一天的数据
----------------------------------------------
-
作者:
男 vmao (毛小毛) ▲▲▲▲▲ -
盒子活跃会员
2017-5-2 22:20:05
5楼: 前几天看到有个兄弟写了个阳历和农历转换的工具。这样是不是就能算出春节,端午,清明这些日期了?
----------------------------------------------

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多