2017-10-13 24 views
1

私は、指定された2つの日付間の作業日数を計算するMySql関数を持っていますが、その中で使用されているロジックを知りたいと思います。次のように SQL関数である:2つの日付間の稼働日数[LOGIC]

CREATE FUNCTION TOTAL_WEEKDAYS(date1 DATE, date2 DATE) 
RETURNS INT 
RETURN ABS(DATEDIFF(date2, date1)) + 1 
- ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY), 
       ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY)))/7 * 2 
- (DAYOFWEEK(IF(date1 < date2, date1, date2)) = 1) 
- (DAYOFWEEK(IF(date1 > date2, date1, date2)) = 7); 

答えて

2
ABS(DATEDIFF(date2, date1)) + 1 
- ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY), 
       ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY)))/7 * 2 
- (DAYOFWEEK(IF(date1 < date2, date1, date2)) = 1) 
- (DAYOFWEEK(IF(date1 > date2, date1, date2)) = 7) 
;  

ABSは(始点が終点後の場合)場合に日付が後方にあり、各結果は正の整数であることを確認するために全体を通して使用されます。

ABS(DATEDIFF(date2, date1)) + 1 

DATEDIFF日付2つの日時値(効果00までの時間を設定:00:両方の日付に00 + 00000)の間の暦日の整数を返します。 DATEDIFFは日付を使用しているため、2日目のの継続時間はであるため、1を加算して補正します。

- ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY), 
       ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY)))/7 * 2 

ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY)ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY)を使用して、両方の日付の週の開始を計算し、それらの日付の間の日数を取得します。その数字を7で割ると、日付間の週数が表示されます。その数値に2を乗じると、スパンに関係する週末の日数が与えられます。以前計算された生の日数からそれらの週末日を差し引いて、日付間の平日の総数を計算します。

与えられた開始/終了日付時刻が個別ので、週末の日に落ちるかもしれしかし:

- (DAYOFWEEK(IF(date1 < date2, date1, date2)) = 1) 

与えられた日付の1が日曜日である場合のいずれかが、1

- (DAYOFWEEK(IF(date1 > date2, date1, date2)) = 7) 

を引きます指定された日付は土曜日です。1を除きます。

週末は土曜日の土曜日の土曜日の除外日である「仕事日」があります。&日曜日。


ここでは、各関数または関数呼び出しのセットを個々の列として分割してそれぞれをトレースするクエリを示します。 2つの日付を指定してサブクエリを調整します。

select 
    date1 
, date2 
, DATEDIFF(date2, date1)  "datediff" 
, ABS(DATEDIFF(date2, date1)) abs_datediff 
, ABS(DATEDIFF(date2, date1)) + 1 diff_2end_dt 
, DAYOFWEEK(date2)    dt2_dow 
, ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY) start_of_wk_dt2 
, DAYOFWEEK(date1) dt1_dow 
, ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY) start_of_wk_dt1 
, DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY), 
       ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY)) diff_wksby7 
, ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY), 
       ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) abs_diff_wksby7    
, ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY), 
       ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY)))/7 * 2 diff_wkends 
, DAYOFWEEK(IF(date1 < date2, date1, date2)) dow_min 
, DAYOFWEEK(IF(date1 > date2, date1, date2)) dow_max 

from (
    select date_add(now(), INTERVAL -34 DAY) as date1, date_add(now(), INTERVAL -2 DAY) as date2 
    ) d 
+0

ありがとうございました。この投稿は本当に私を理解するのを助けました。 (Y) –

関連する問題