3 回答

TA貢獻1859條經驗 獲得超6個贊
這個表達 -
5 * (DATEDIFF(@E, @S) DIV 7) + MID('0123444401233334012222340111123400012345001234550', 7 * WEEKDAY(@S) + WEEKDAY(@E) + 1, 1)
計算開始日期@S和結束日期@E之間的工作日數。
假設結束日期(@E)不在開始日期之前(@S)。與DATEDIFF兼容,因為相同的開始日期和結束日期為零工作日。忽略假期。
數字串的構造如下。創(chuàng)建一個開始日和結束日的表,行必須以星期一(WEEKDAY 0)開頭,列也必須以星期一開始。從左上角到右下角填寫對角線,全部為0(即星期一到星期一,星期二和星期二之間有0個工作日,等等)。對于每天從對角線開始(必須始終為0)并填寫右側的列,一次一天。如果您在周末(非工作日)列登陸,則工作日數不會更改,而是從左側開始。否則,工作日數會增加一個。當你到達行循環(huán)的末尾回到同一行的開頭并繼續(xù)直到你再次到達對角線。然后繼續(xù)下一行。
例如,假設周六和周日不是工作日 -
| M T W T F S S
-|--------------
M| 0 1 2 3 4 4 4
T| 4 0 1 2 3 3 3
W| 3 4 0 1 2 2 2
T| 2 3 4 0 1 1 1
F| 1 2 3 4 0 0 0
S| 1 2 3 4 5 0 0
S| 1 2 3 4 5 5 0
然后將表中的49個值連接到字符串中。
如果您發(fā)現任何錯誤,請告訴我。
-Edit改進表:
| M T W T F S S
-|--------------
M| 0 1 2 3 4 4 4
T| 4 0 1 2 3 3 3
W| 3 4 0 1 2 2 2
T| 2 3 4 0 1 1 1
F| 1 2 3 4 0 0 0
S| 0 1 2 3 4 0 0
S| 0 1 2 3 4 4 0
改進的字符串:'0123444401233334012222340111123400001234000123440'
表達改善:
5 * (DATEDIFF(@E, @S) DIV 7) + MID('0123444401233334012222340111123400001234000123440', 7 * WEEKDAY(@S) + WEEKDAY(@E) + 1, 1)

TA貢獻1794條經驗 獲得超7個贊
該解決方案使用與Rodger基本相同的方法,除了生成矩陣的方法要復雜得多。注意:此解決方案的此輸出與NETWORKDAYS不兼容。
與Rodger的解決方案一樣,這可以計算開始日期(@S)和結束日期(@E)之間的工作日數,而無需定義存儲過程。它假定結束日期不在開始日期之前。使用相同的開始和結束日期將產生0.不考慮假期。
這與Rodger的解決方案之間的主要區(qū)別在于矩陣和結果的數字串是由一個我沒有包含的復雜算法構造的。該算法的輸出由單元測試驗證(參見下面的測試輸入和輸出)。在矩陣中,任何給定的x和y值對(WEEKDAY(@S)和WEEKDAY(@E)的交集產生兩個值之間的工作日差異。分配順序實際上并不重要,因為兩者被加在一起繪制位置。
營業(yè)日為周一至周五
| M T W T F S S
-|--------------
M| 0 1 2 3 4 5 5
T| 5 0 1 2 3 4 4
W| 4 5 0 1 2 3 3
T| 3 4 5 0 1 2 2
F| 2 3 4 5 0 1 1
S| 0 1 2 3 4 0 0
S| 0 1 2 3 4 5 0
表中的49個值連接成以下字符串:
0123455501234445012333450122234501101234000123450
最后,正確的表達是:
5 * (DATEDIFF(@E, @S) DIV 7) + MID('0123455501234445012333450122234501101234000123450', 7 * WEEKDAY(@S) + WEEKDAY(@E) + 1, 1)
我已使用此解決方案驗證了以下輸入和輸出:
Sunday, 2012-08-26 -> Monday, 2012-08-27 = 0
Sunday, 2012-08-26 -> Sunday, 2012-09-02 = 5
Monday, 2012-08-27 -> Tuesday, 2012-08-28 = 1
Monday, 2012-08-27 -> Monday, 2012-09-10 = 10
Monday, 2012-08-27 -> Monday, 2012-09-17 = 15
Monday, 2012-08-27 -> Tuesday, 2012-09-18 = 16
Monday, 2012-08-27 -> Monday, 2012-09-24 = 20
Monday, 2012-08-27 -> Monday, 2012-10-01 = 25
Tuesday, 2012-08-28 -> Wednesday, 2012-08-29 = 1
Wednesday, 2012-08-29 -> Thursday, 2012-08-30 = 1
Thursday, 2012-08-30 -> Friday, 2012-08-31 = 1
Friday, 2012-08-31 -> Saturday, 2012-09-01 = 1
Saturday, 2012-09-01 -> Sunday, 2012-09-02 = 0
Sunday, 2012-09-02 -> Monday, 2012-09-03 = 0
Monday, 2012-09-03 -> Tuesday, 2012-09-04 = 1
Tuesday, 2012-09-04 -> Wednesday, 2012-09-05 = 1
Wednesday, 2012-09-05 -> Thursday, 2012-09-06 = 1
Thursday, 2012-09-06 -> Friday, 2012-09-07 = 1
Friday, 2012-09-07 -> Saturday, 2012-09-08 = 1
Saturday, 2012-09-08 -> Sunday, 2012-09-09 = 0
Monday, 2012-09-24 -> Sunday, 2012-10-07 = 10
Saturday, 2012-08-25 -> Saturday, 2012-08-25 = 0
Saturday, 2012-08-25 -> Sunday, 2012-08-26 = 0
Saturday, 2012-08-25 -> Monday, 2012-08-27 = 0
Saturday, 2012-08-25 -> Tuesday, 2012-08-28 = 1
Saturday, 2012-08-25 -> Wednesday, 2012-08-29 = 2
Saturday, 2012-08-25 -> Thursday, 2012-08-30 = 3
Saturday, 2012-08-25 -> Friday, 2012-08-31 = 4
Saturday, 2012-08-25 -> Sunday, 2012-09-02 = 0
Monday, 2012-08-27 -> Monday, 2012-08-27 = 0
Monday, 2012-08-27 -> Tuesday, 2012-08-28 = 1
Monday, 2012-08-27 -> Wednesday, 2012-08-29 = 2
Monday, 2012-08-27 -> Thursday, 2012-08-30 = 3
Monday, 2012-08-27 -> Friday, 2012-08-31 = 4
Monday, 2012-08-27 -> Saturday, 2012-09-01 = 5
Monday, 2012-08-27 -> Sunday, 2012-09-02 = 5
添加回答
舉報