2010-02-13 5 views
1

다른 해결책은 "근무일"이 의미하는 바리에이션이 다를 수 있지만 내 경우에는 월요일부터 금요일까지를 의미합니다.2 일 간의 TIP 작업 일수 계산 - T-SQL?

기본적으로 내가 계산을 수행하는 기능을 생성했으며 현재 솔루션이 작동합니다. 내 관심사 (그리고이 질문을하는 이유)는 함수가 매우 높은 빈도로 호출 되었기 때문에 이것이 이것을 달성하는 나쁜 방법이라고 걱정한다. 지난 3 개월 동안 평균 생산 시간은 44ms 인 생산 시스템에서 1,200 만 회라고합니다.

이것이 해결책을 얻는 올바른 방법인지 궁금합니다.

SELECT MYTABLE.EntryDate 
    ,dbo.fn_WorkDays(MYTABLE.EntryDate, getutcdate()) as WorkingDays 
    FROM MYTABLE          

을 MyTable 모든 다른 날짜로 5000 개 행을 포함 할 수있다 : 나는 이러한 유형의 쿼리를 실행하는 것입니다 그것의 사용의 간단한 예를 들어

CREATE FUNCTION [dbo].[fn_WorkDays] 
    (
    @StartDate DATETIME, 
    @EndDate DATETIME = NULL [email protected] 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 

: 첫째로 여기

은 내가 만든 기능입니다 EntryDate 칼럼 (함수에 대한 5000 호출)

내 질문은 내가 이것을하고있는 방식으로 여기에 뭔가 빠져있다. loo를 만드는 것이 유익 할까? 이것에 대한 KUP 테이블

어떤 생각, 개선 또는 권고 감상 할 수있다 (하지만 그 날짜의 조합의 많은입니다) ... 여기에 두 가지 문제가있다

+0

이 답변을보고 메모를 비교해보십시오. http://stackoverflow.com/questions/1828948/mysql-function-to-find-the-number-of-working-days-between-two-dates/1828991 # 1828991 –

+0

추가 필드 (계산 된 필드)를 추가하고 값이 변경된 경우에만 일의 차이를 업데이트 할 수 있습니까? 나는 매번 차이점을 얻는 것이 무엇을 의미합니까? – shahkalpesh

+0

항상 저장된 날짜와 오늘을 비교하면 ... 하루에 적어도 한 번 업데이트해야합니다 (옵션 임) –

답변

2

UDF tbh로 할 수있는 일이 많지 않다고 생각합니다. SQL에서 이와 같이 런타임에 계산하면 항상 어느 정도 히트가 발생합니다.

이상적으로 (전체 그림을 알 수 없기 때문에 가능하지 않을 수도 있습니다.) 제가 생각하기에 테이블에 WorkingDays 번호를 저장하고 레코드를 만들 때 한 번 계산하는 것입니다. 그게 가능하지 않다면 (즉, 레코드가 생성 될 때 "종료일"이 없으므로 "now"를 사용하여 해결해야합니다.) 그러면 야간에 예정된 작업을 검토하고 모든 작업을 다시 계산할 것입니다 특정 레코드가 매일 업데이트되도록 설정하십시오. 그런 다음 "종료 날짜"가 입력되면이 레코드는이 일괄 업데이트에 포함되지 않습니다.

이점은 계산량을 더 적은 기간으로 줄이고 하루에 한 번만 계산하는 것입니다. 쿼리는 테이블에서 근무일 번호를 읽는 것만 큼 훨씬 간단하고 성능이 향상됩니다.

이것이 옵션이 아니라면 프런트 엔드에서 계산을 수행하고 DB에서 히트를 제거 할 것을 제안합니다.

+0

계산은 항상 오늘부터 기초이기 때문에 레코드 생성 시점에서가 아니라 매일 값을 할당해야합니다 (레코드 생성시 값을 초기화하는 것뿐만 아니라). 좋은 호출입니다. –

+0

@ 시몬 - 나는 그럴 것이라고 생각했다. 그러나 야간 업데이트 접근법을 고려해 볼 가치가 있다고 생각합니다. 하루에 한 번 업데이트하면보고 성능이 크게 향상 될 수 있습니다. 특히 하루 중 여러 번 계산이 수행되는 경우 – AdaTheDev

0

:

  1. 의 수를 계산은 두 날짜 사이의 일수,
  2. 주는 날짜가 "영업일"인지 여부를 식별합니다.

두 번째는 "주말"대 "평일", 휴일 (세속 종교, 법률), 등과 같은 쉬운 것들을 포함

당신은 모두를 해결해야합니다.

첫 번째 방법은 관계형 데이터베이스에 도움이되는 기능이 있기 때문에 더 쉽습니다. 로케일과 비즈니스에 따라 변경되기 때문에 더 어렵고 변수가 많은 것은 두 번째입니다.

+0

내 요구 사항은 그보다 간단합니다. 기본적으로 휴일 제외는 기본적으로 주말 제외 ... 내 솔루션은 그렇게합니다. 단지 제가 가지고 있는지 확인하고 싶습니다. 여기에서 트릭을 놓치지 않고 가장 효과적인 방식으로 솔루션을 실행하고 있습니다. –

+0

크리스마스, 새해 등 - 걱정할 필요가 없습니다. 그렇다면 더 쉬운 문제입니다. – duffymo

+0

지금은 아니오, 내 문제에 대한 해결책을 구현 한 것에 대해 우려하고 있습니다. –