我意识到不同的解决方案会对“工作日”的含义有不同的变化,但就我而言,我的意思是周一至周五。
基本上我已经创建了一个函数来为我做计算,我当前的解决方案是有效的。我担心(以及提出这个问题的原因)是我担心这是实现这个目标的一种不好的方法,因为这个函数的调用频率非常高。在过去的3个月里,它在生产系统上被称为1200万次,平均工作时间为44ms。
这让我想知道这是否是实现解决方案的正确方法。
首先,这是我创建的功能:
CREATE FUNCTION [dbo].[fn_WorkDays]
(
@StartDate DATETIME,
@EndDate DATETIME = NULL --@EndDate replaced by @StartDate when DEFAULTed
)
RETURNS INT
AS
BEGIN
--===== Declare local variables
--Temporarily holds @EndDate during date reversal
DECLARE @Swap DATETIME
--===== If the Start Date is null, return a NULL and exit
IF @StartDate IS NULL
RETURN NULL
--===== If the End Date is null, populate with Start Date value
-- so will have two dates (required by DATEDIFF below)
IF @EndDate IS NULL
SELECT @EndDate = @StartDate
--===== Strip the time element from both dates (just to be safe) by converting
-- to whole days and back to a date. Usually faster than CONVERT.
-- 0 is a date (01/01/1900 00:00:00.000)
SELECT @StartDate = DATEADD(dd,DATEDIFF(dd,0,@StartDate),0),
@EndDate = DATEADD(dd,DATEDIFF(dd,0,@EndDate) ,0)
--===== If the inputs are in the wrong order, reverse them
IF @StartDate > @EndDate
SELECT @Swap = @EndDate,
@EndDate = @StartDate,
@StartDate = @Swap
--===== Calculate and return the number of workdays using the
-- input parameters. This is the meat of the function.
-- This is really just one formula with a couple of parts
-- that are listed on separate lines for documentation
-- purposes.
RETURN (
SELECT
--Start with total number of days including weekends
(DATEDIFF(dd,@StartDate,@EndDate)+1)
--Subtact 2 days for each full weekend
-(DATEDIFF(wk,@StartDate,@EndDate)*2)
--If StartDate is a Sunday, Subtract 1
-(CASE WHEN DATENAME(dw,@StartDate) = 'Sunday'
THEN 1
ELSE 0
END)
--If EndDate is a Saturday, Subtract 1
-(CASE WHEN DATENAME(dw,@EndDate) = 'Saturday'
THEN 1
ELSE 0
END)
)
END
作为其使用的一个简单示例,我将运行此类查询:
SELECT MYTABLE.EntryDate
,dbo.fn_WorkDays(MYTABLE.EntryDate, getutcdate()) as WorkingDays
FROM MYTABLE
MyTable可以包含5000行,所有条目在EntryDate列中都有不同的日期(5000次调用函数)
我的问题是我在这里错过了一些我正在做的事情,为此创建一个查找表是有益的(但这是很多日期组合)
任何想法,改进或建议都将受到赞赏......
答案 0 :(得分:2)
我不认为你可以用UDF做很多事情 - 在运行时计算它在SQL中总是会在某种程度上受到打击。
所以,理想情况下(这可能不可能,因为我不知道全貌),我认为我要做的是将工作日数存储在表中并在创建记录时计算它。如果那是不可能的(即创建记录时,你没有“结束日期”,所以必须使用“现在”计算出来)然后我会考虑每晚预定的工作去重新计算所有那些特定记录,以便它们每天更新 - 然后当输入“结束日期”时,该记录不会包含在此批量更新中。
这样做的好处是,您可以将计算卸载到更安静的时间段,并且每天只进行一次计算。查询变得更简单,更高效,因为它只能从表中读取WorkingDays编号。
如果这不是一个选项,那么我建议在前端进行计算,从数据库中删除命中。
答案 1 :(得分:0)
这里有两个问题:
第二种包括“平日”与“周末”,假期(世俗,宗教和法律等)等简单的等等。
你需要解决这两个问题。
第一个更容易,因为关系数据库将具有帮助您的功能。这是第二个更难,更多变量,因为它会因地区和业务而变化。