现有一容量非常大的数据表(千万级),其中有一日期字段类型,需要求当天日期与该日期之差小于X日,且要排除节假日和双休日。
由于X是不定的,所以不能够建辅助字段给日期在扣除节假日和双休日的基础上加X日。
期望能够求得一最讲究效率的算法,快速求出当前日期与数据表中日期字段,排除节假日和双休日后,小于X日的算法。
节假日和双休日的表格可以任意定义,可以为它们建立任意辅助字段。
---------------------------------------------------------------
对于这个问题,解决的方法可能说是比较确定的,就是建立休息日期表(双休日和节假日,双休日的日期是确定的,)
在sql中,是通过索引来提高查询效率的,所以要有效的查询数据的关键,是想办法在日期字段上建立索引,并且利用索引进行查询
而一般人在查询离当前日期(或指定日期)x天内的记录,习惯采用下面的方法:
select * from tb where datediff(day,日期字段,getdate()) between 0 and x
这种方法由于把日期字段放入了函数中,所以即使在日期字段上建立索引,也无法利用索引来提高效率的
而要使
select * from tb where datediff(day,日期字段,getdate()) between 0 and x
能够利用上索引,则改查询算法为:
select * from tb where 日期字段 between datediff(day,-x,convert(char(10),getdate(),120)) and convert(char(10),getdate(),120)
就行了
所以楼主的这种问题的实质,就是把处理算法调整为类似上面的,并且考虑节假日的处理就OK
/*--建立节假日表
按常理推算,双休日都是可以直接计算的,但考虑到实际工作中,会出现因节假日
而调整双休日为工作日的情况,所以把双休日和节假日定义都纳入节假表中,处理时仅根据
节假日表确定指定日期是否为工作日
--*/
create table tb_Holiday(
HDate smalldatetime primary key clustered,
Name nvarchar(50) not null)
go
--处理的自定义函数
create function f_workdateadd(
@dt datetime,--要添加工作天数的日期
@workday int--要增加的工作天
)returns datetime
as
begin
set @dt=convert(char(10),@dt,120) --去掉时间部分(防止传入的参数中有时间部分,影响处理)
if @workday>0
while @workday>0
select @dt=@dt+@workday
,@workday=count()
from tb_Holiday
where HDate between @dt and @dt+@workday
else
while @workday<0
select @dt=@dt+@workday,@workday=-count()
from tb_Holiday
where HDate between @dt+@workday and @dt
return(@dt)
end
go
--查询最近10个工作日内的记录,这样调用(注意在日期字段上建立索引,否则无法提高效率)
select * from tb where 日期 between dbo.f_workdateadd(getdate(),-10) and convert(char(10),getdate(),120)