1

指定された 2 つの日付の間の稼働日数 (月曜日から金曜日) を返す SQL クエリを作成する必要があります。

これを行うための最も効率的な方法は何だろうと思っていましたか?

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          
ELSE 0               END)            --If EndDate is a Saturday, Subtract 1 
FROM dual

また、クリスマスやボクシング デーなどの祝日をこのカウントから除外できると便利です。

何か案は?

4

6 に答える 6

3

それはとても簡単です:

    SQL> Select count(*)
      2  from ( select rownum rnum
      3          from all_objects
      4        where rownum <= to_date('18-dec-2009','dd-mon-yyyy') - 
    to_date('16-nov-2009')+1 )
      5    where to_char( to_date('16-nov-2009','dd-mon-yyyy')+rnum-1, 'DY' )
      6                not in ( 'SAT', 'SUN' )


      COUNT(*)
    ----------
            25

    SQL> Select to_char( to_date('16-nov-2009','dd-mon-yyyy')+rnum-1, 'DY dd-mon-yyyy' )
      2  from ( select rownum rnum
      3          from all_objects
      4        where rownum <= to_date('18-dec-2009','dd-mon-yyyy') - to_date('16-nov-2009')+1 )
      5    where to_char( to_date('16-nov-2009','dd-mon-yyyy')+rnum-1, 'DY' )
      6                not in ( 'SAT', 'SUN' )


DAY_DATE
---------------
MON 16-nov-2009
TUE 17-nov-2009
WED 18-nov-2009
THU 19-nov-2009
FRI 20-nov-2009
MON 23-nov-2009
TUE 24-nov-2009
WED 25-nov-2009
THU 26-nov-2009
FRI 27-nov-2009
MON 30-nov-2009
TUE 01-dec-2009
WED 02-dec-2009
THU 03-dec-2009
FRI 04-dec-2009
MON 07-dec-2009
TUE 08-dec-2009
WED 09-dec-2009
THU 10-dec-2009
FRI 11-dec-2009
MON 14-dec-2009
TUE 15-dec-2009
WED 16-dec-2009
THU 17-dec-2009
FRI 18-dec-2009

25 rows selected.
于 2012-10-17T15:04:35.067 に答える
1

これが例です

with given_days(d) as(
  select <<start_date>> + level - 1
    from dual
  connect by level < = (<<end_date>> - <<start_date>>) + 1
)
select count(*)
  from given_days
where to_char(d, 'DY', 'NLS_DATE_LANGUAGE=english') not in ('SUN', 'SAT')

デモンストレーション

HR\XE> with given_days as(
  2    select (to_date('&&1', 'dd.mm.yyyy') + level - 1) as g_day
  3      from dual
  4    connect by level < = (to_date('&2', 'dd.mm.yyyy') - to_date('&&1', 'dd.mm.yyyy')) + 1
  5  )
  6  select count(g_day) as cnt
  7    from given_days
  8  where to_char(g_day, 'DY', 'NLS_DATE_LANGUAGE=english') not in ('SUN', 'SAT');
Enter value for 1: 10.10.2012
old   2:   select to_date('&&1', 'dd.mm.yyyy') + level - 1
new   2:   select to_date('10.10.2012', 'dd.mm.yyyy') + level - 1
Enter value for 2: 17.10.2012
old   4:   connect by level < = (to_date('&2', 'dd.mm.yyyy') - to_date('&&1', 'dd.mm.yyyy')) + 1
new   4:   connect by level < = (to_date('17.10.2012', 'dd.mm.yyyy') - to_date('10.10.2012', 'dd.mm.yyyy')) + 1

  cnt                                                                     
----------                           
   6                                                                      
于 2012-10-17T11:23:43.593 に答える
1

それは次の方法で達成できます。

select  SUM(decode ( to_CHAR((sysdate-ROWNUM),'DY'),'SUN',0,'SAT',0,1)) from all_objects where rownum < sysdate -  (sysdate -9) 
于 2014-04-09T22:15:16.057 に答える
0

これは、ある日が稼働日かどうかを示す列を含むカレンダー テーブルを既に取得していると仮定して、私が行う方法です。

sum(case when workingday then 1 else 0 end)
over (order by calendardate rows unbounded preceding)

カレンダーへの 2 つの結合と、p_start_date と p_end_date の workday_nums の単純な違いです。

于 2013-08-21T15:12:22.467 に答える
0

どうぞ...

  1. まず、週末を除いて休日テーブルに何日入ったかを確認します。
  2. 2 つの日付の間の営業日 (月曜日から金曜日) を取得し、その後、休日の日を差し引きます。

    create or replace
    FUNCTION calculate_business_days (p_start_date IN DATE, p_end_date IN DATE)
            RETURN NUMBER IS
            v_holidays     NUMBER;
            v_start_date   DATE   := TRUNC (p_start_date);
            v_end_date     DATE   := TRUNC (p_end_date);
            BEGIN
            IF v_end_date >= v_start_date
            THEN
                    SELECT COUNT (*)
                    INTO v_holidays
                    FROM holidays
                    WHERE day BETWEEN v_start_date AND v_end_date
                    AND day NOT IN (
                            SELECT hol.day 
                            FROM holidays hol 
                            WHERE MOD(TO_CHAR(hol.day, 'J'), 7) + 1 IN (6, 7)
                    );
    
            RETURN   GREATEST (NEXT_DAY (v_start_date, 'MON') - v_start_date - 2, 0)
                 +   (  (  NEXT_DAY (v_end_date, 'MON')
                         - NEXT_DAY (v_start_date, 'MON')
                        )
                      / 7
                     )
                   * 5
                 - GREATEST (NEXT_DAY (v_end_date, 'MON') - v_end_date - 3, 0)
                 - v_holidays;
            ELSE
                    RETURN NULL;
            END IF;
    END calculate_business_days;
    

その後、次のようにテストできます。

    select 
            calculate_business_days('21-AUG-2013','28-AUG-2013') as business_days 
    from dual;
于 2013-08-21T15:06:20.103 に答える