热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

扣除节假日高效算法

在日常开发中,有时候需要扣除节假日,本人实际开发中使用了一套比较好的办法与大家讨论.表结构ER设计如下:其中:节假日表,是存计算好的节假日结果.并且把日期换成整形日期,建立索引提高判断速度,只要节

在日常开发中,有时候需要扣除节假日,本人实际开发中使用了一套比较好的办法与大家讨论.
表结构ER设计如下:


其中:节假日表,是存计算好的节假日结果.并且把日期换成"整形日期",建立索引提高判断速度,
只要节假日,变成,当晚就可以通过DTS最新计算节假日表,
存储过程如下:

CREATE     Procedure  sp_holiday
    
@YEAR   int
AS
    
-- 产生节假日数据
     -- exec sp_holiday 2005
     SET  NOCOUNT  ON
    
    
-- 判断是否需要计算
     IF  ( SELECT  SET_IS_REDO  FROM  TJ_SETTINGS  WHERE  SET_YEAR  =   @YEAR =   1
    
BEGIN
    
        
BEGIN   TRAN
        
        
DELETE   FROM  TJ_HOLIDAY  WHERE  HOL_YEAR  =   @YEAR
        
DECLARE   @SQL   VARCHAR ( 100 ),  @THIS_DATE   SMALLDATETIME @BEGIN_DATE   SMALLDATETIME @END_DATE   SMALLDATETIME @HOL_NAME   VARCHAR ( 50 ),  @INDEX   TINYINT @IS_WEEK   TINYINT
        
-- 初始化双休日数据
         CREATE   TABLE  #WEEK (WEEK_DAY  TINYINT   PRIMARY   KEY   NOT   NULL , IS_WEEK  TINYINT   NULL )
        
SET   @INDEX   =   0
        
WHILE  ( @INDEX   <   7 )
        
BEGIN
            
SET   @SQL   =   ' INSERT INTO #WEEK (WEEK_DAY, IS_WEEK) SELECT  '   +   CAST ( @INDEX   AS   CHAR ( 1 ))  +   ' , WK_ '   +   CAST ( @INDEX   AS   CHAR ( 1 ))  +   '  FROM TJ_WEEK WHERE WK_YEAR =  '   +   CAST ( @YEAR   AS   CHAR ( 4 ))
            
EXEC ( @SQL )
            
SET   @INDEX   =   @INDEX   +   1
        
END
        
-- 每一天判断
         SET   @BEGIN_DATE   =   CONVERT ( SMALLDATETIME CAST ( @YEAR   AS   CHAR ( 4 ))  +   ' -01-01 ' 120 )
        
SET   @END_DATE   =   DATEADD ( YEAR 1 @BEGIN_DATE )
        
SET   @THIS_DATE   =   @BEGIN_DATE
        
WHILE  ( @THIS_DATE   <   @END_DATE )
        
BEGIN
            
-- 非节假日
             IF   EXISTS  ( SELECT   *   FROM  TJ_NONFERIA  WHERE  NFR_YEAR  =   @YEAR   AND  NFR_DATE  =   @THIS_DATE )
            
begin
                
SET   @THIS_DATE   =   DATEADD ( DAY 1 @THIS_DATE )
                
CONTINUE
            
end
            
-- 节日
             ELSE   IF   EXISTS  ( SELECT   *   FROM  TJ_FERIA  WHERE  FER_YEAR  =   @YEAR   AND  FER_DATE  =   @THIS_DATE )
            
BEGIN
                
SELECT   @HOL_NAME   =  FER_NAME  FROM  TJ_FERIA  WHERE  FER_YEAR  =   @YEAR   AND  FER_DATE  =   @THIS_DATE
                
INSERT   INTO  TJ_HOLIDAY (HOL_YEAR, HOL_DATE_INT, HOL_DATE, HOL_NAME) 
                
VALUES  ( @YEAR FLOOR ( CONVERT ( FLOAT @THIS_DATE )),  @THIS_DATE @HOL_NAME )
            
END
            
-- 休息日
             ELSE
            
BEGIN
                
SELECT   @IS_WEEK   =  IS_WEEK  FROM  #WEEK  WHERE  WEEK_DAY  =  ( DATEPART (WEEKDAY,  @THIS_DATE -   1 )
                
IF  ( @IS_WEEK   >   0 )
                    
INSERT   INTO  TJ_HOLIDAY (HOL_YEAR, HOL_DATE_INT, HOL_DATE, HOL_NAME) 
                    
VALUES  ( @YEAR FLOOR ( CONVERT ( FLOAT @THIS_DATE )),  @THIS_DATE DATENAME (WEEKDAY,  @THIS_DATE ))
            
END
            
SET   @THIS_DATE   =   DATEADD ( DAY 1 @THIS_DATE )
        
END
        
        
-- 重新设置计算标记
         UPDATE  TJ_SETTINGS  SET  SET_IS_REDO  =   0   WHERE  SET_YEAR  =   @YEAR
        
        
IF   @@ERROR   =   0
            
COMMIT   TRAN
        
ELSE  
            
ROLLBACK   TRAN
        
        
DROP   TABLE  #WEEK
    
    
END
    
    
SET  NOCOUNT  OFF

GO

/**/ /******************************************************************
* 名称: 工作日重新
* 作者: WANGYJ
* 时间: 2005-5-17
*
* -----------------------------------------------------------------
* 版本        时间            作者        备注
*
* V1.00        2005-5-3    WANGYJ        创建
* -----------------------------------------------------------------
*****************************************************************
*/

create    Procedure  sp_holiday_ALL
    
AS
    
DECLARE  my_cursor  CURSOR   for
    
select  SET_YEAR  from  TJ_SETTINGS   where  SET_IS_REDO  =   1
    
DECLARE   @year   varchar ( 4 )
    
    
open  my_cursor
    
FETCH   NEXT   FROM  my_cursor 
    
INTO   @year
WHILE   @@FETCH_STATUS   =   0
BEGIN
    
exec  risk.sp_holiday  @year
  
    
FETCH   NEXT   FROM  my_cursor 
    
INTO   @year
       
END
   
CLOSE  my_cursor
   
DEALLOCATE  my_cursor

GO

节假日扣除函数如下:




CREATE      FUNCTION  risk.CalcDay
(
    
@Diff   smallint ,         -- 差别值.正数为加,负数减
     @D_Date   datetime        -- 差别日期
)
RETURNS   datetime
AS
    
BEGIN
        
declare   @ordDate   datetime
        
set   @ordDate   =   @D_Date
        
set   @D_Date   =   convert ( char ( 10 ),  @D_Date 120 )   -- 去掉时间部分(防止传入的参数中有时间部分,影响处理)
         if   @Diff   >   0
        
begin
            
while   @Diff   >   0
            
begin
                
select   @D_Date   =   @D_Date   +   @Diff @Diff   =   count ( * from  TJ_HOLIDAY 
                
where  HOL_DATE_INT  >   FLOOR ( CONVERT ( FLOAT @D_Date ))  AND  HOL_DATE_INT  <=   FLOOR ( CONVERT ( FLOAT @D_Date   +   @Diff ))
            
end
        
end
        
else
        
begin
            
while   @Diff   <   0
            
begin
                
select   @D_Date   =   @D_Date   +   @Diff @Diff   =-   count ( * from  TJ_HOLIDAY 
                
where  HOL_DATE_INT  <   FLOOR ( CONVERT ( FLOAT @D_Date ))  AND  HOL_DATE_INT  >=   FLOOR ( CONVERT ( FLOAT @D_Date   +   @Diff ))
            
end
        
end
    
set   @D_Date   =   dateadd (hour, datepart (hour, @ordDate ), @D_Date )
    
set   @D_Date   =   dateadd (minute, datepart (minute, @ordDate ), @D_Date )
    
set   @D_Date   =   dateadd (second, datepart (second, @ordDate ), @D_Date )
    
return ( @D_Date )
    
END






这样就可以使用了,dbo.CaclDay(-5,getdate())就是扣除节假以后的5天前的数据

希望对大家有帮助


推荐阅读
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了游标的使用方法,并以一个水果供应商数据库为例进行了说明。首先创建了一个名为fruits的表,包含了水果的id、供应商id、名称和价格等字段。然后使用游标查询了水果的名称和价格,并将结果输出。最后对游标进行了关闭操作。通过本文可以了解到游标在数据库操作中的应用。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文主要复习了数据库的一些知识点,包括环境变量设置、表之间的引用关系等。同时介绍了一些常用的数据库命令及其使用方法,如创建数据库、查看已存在的数据库、切换数据库、创建表等操作。通过本文的学习,可以加深对数据库的理解和应用能力。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 本文介绍了解决Facebook脸书面试题中插入区间的方法,通过模拟遍历的方式判断当前元素与要插入元素的关系,找到插入点并将新区间插入。同时对算法的时间复杂度和空间复杂度进行了分析。 ... [详细]
  • 本文介绍了汉诺塔问题的迭代算法实现,通过递归的方式将盘子从一个地方搬到另一个地方,并打印出移动的顺序。详细介绍了算法的思路和步骤,以及示例代码的运行结果。 ... [详细]
  • 本文介绍了一种轻巧方便的工具——集算器,通过使用集算器可以将文本日志变成结构化数据,然后可以使用SQL式查询。集算器利用集算语言的优点,将日志内容结构化为数据表结构,SPL支持直接对结构化的文件进行SQL查询,不再需要安装配置第三方数据库软件。本文还详细介绍了具体的实施过程。 ... [详细]
author-avatar
执子之手2502891083
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有