2012-03-18 131 views
3

我需要計算MySQL中兩個日期(週六和週日除外)之間的差異(以天爲單位)。也就是說,天數之差減去週六和週日之間的差額。兩個日期之間的計數天數,不包括週末(僅限MySQL)

在那一刻,我簡直度日如年使用:

SELECT DATEDIFF('2012-03-18', '2012-03-01') 

這回17,但我想不包括週末,所以我想12(因爲第3和第4,第10和第11和17都週末日)。

我不知道從哪裏開始。我知道WEEKDAY()函數和所有相關函數,但我不知道如何在這種情況下使用它們。

+1

@xdazz我沒有函數來獲得MySQL中兩個日期之間的差異。 'DATEDIFF'只能在幾天內運行,而不是像TSQL中的DATEDIFF那樣。 – 2012-03-18 11:39:44

+0

@xdazz,公平地說,這是一個不同的RDBMS,但是,這是[MySQL函數找到兩個日期之間的工作天數]的可能重複(http://stackoverflow.com/questions/1828948/mysql-function - 找到工作日數 - 兩日期間) – Ben 2012-03-18 12:40:18

+0

您是否想要排除節假日? – biziclop 2012-03-18 13:37:48

回答

4

插圖:

mtwtfSSmtwtfSS 
    123456712345 one week plus 5 days, you can remove whole weeks safely 
    12345------- you can analyze partial week's days at start date 
    -------12345 or at (end date - partial days) 

僞代碼:

@S   = start date 
@E   = end date, not inclusive 
@full_weeks = floor((@[email protected])/7) 
@days  = (@[email protected]) - @full_weeks*7 OR (@[email protected]) % 7 

SELECT 
    @full_weeks*5 -- not saturday+sunday 
+IF(@days >= 1 AND weekday(S+0)<=4, 1, 0) 
+IF(@days >= 2 AND weekday(S+1)<=4, 1, 0) 
+IF(@days >= 3 AND weekday(S+2)<=4, 1, 0) 
+IF(@days >= 4 AND weekday(S+3)<=4, 1, 0) 
+IF(@days >= 5 AND weekday(S+4)<=4, 1, 0) 
+IF(@days >= 6 AND weekday(S+5)<=4, 1, 0) 
-- days always less than 7 days 
+0

我想我明白了。我會嘗試並讓你知道。 – 2012-03-18 13:25:35

+2

你的代碼中有錯誤嗎?在SELECT之後,不必是'@ full_weeks * 5'而不是'@ full_weeks * 2'? – 2012-03-18 13:33:43

+0

是的,我在工作日的週末翻轉,對不起。 – biziclop 2012-03-18 13:34:35

1
Below function will give you the Weekdays, Weekends, Date difference with proper results: 

You can call the below function like, 
select getWorkingday('2014-04-01','2014-05-05','day_diffs'); 
select getWorkingday('2014-04-01','2014-05-05','work_days'); 
select getWorkingday('2014-04-01','2014-05-05','weekend_days'); 




    DROP FUNCTION IF EXISTS PREPROCESSOR.getWorkingday; 
    CREATE FUNCTION PREPROCESSOR.`getWorkingday`(d1 datetime,d2 datetime, retType varchar(20)) RETURNS varchar(255) CHARSET utf8 
    BEGIN 
    DECLARE dow1, dow2,daydiff,workdays, weekenddays, retdays,hourdiff INT; 
     declare newstrt_dt datetime; 
     SELECT dd.iDiff, dd.iDiff - dd.iWeekEndDays AS iWorkDays, dd.iWeekEndDays into daydiff, workdays, weekenddays 
     FROM (
     SELECT 
     dd.iDiff, 
     ((dd.iWeeks * 2) + 
      IF(dd.iSatDiff >= 0 AND dd.iSatDiff < dd.iDays, 1, 0) + 
      IF (dd.iSunDiff >= 0 AND dd.iSunDiff < dd.iDays, 1, 0)) AS iWeekEndDays 
      FROM (
      SELECT dd.iDiff, FLOOR(dd.iDiff/7) AS iWeeks, dd.iDiff % 7 iDays, 5 - dd.iStartDay AS iSatDiff, 6 - dd.iStartDay AS iSunDiff 
     FROM (
      SELECT 
      1 + DATEDIFF(d2, d1) AS iDiff, 
      WEEKDAY(d1) AS iStartDay 
     ) AS dd 
     ) AS dd 
    ) AS dd ; 
     if(retType = 'day_diffs') then 
     set retdays = daydiff; 
    elseif(retType = 'work_days') then 
     set retdays = workdays; 
    elseif(retType = 'weekend_days') then 
     set retdays = weekenddays; 
    end if; 
     RETURN retdays; 
     END; 


Thank You. 
Vinod Cyriac. 
Bangalore 
6

簡單地嘗試使用簡單的功能:

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); 

測試:

SELECT TOTAL_WEEKDAYS('2013-08-03', '2013-08-21') weekdays1, 
     TOTAL_WEEKDAYS('2013-08-21', '2013-08-03') weekdays2; 

結果:

| WEEKDAYS1 | WEEKDAYS2 | 
------------------------- 
|  13 |  13 | 
1

IT我對您有所幫助

波紋管邏輯只顯示有多少天 像

sun mon 

1  2 ..................... 

DELIMITER $$ 
DROP FUNCTION IF EXISTS `xx`.`get_weekday` $$ 
CREATE FUNCTION `xx`.`get_weekday` (first_date date, last_date date, curr_week_day int) RETURNS INT 
BEGIN 
DECLARE days_tot int; 
DECLARE whole_weeks int; 
DECLARE first_day int; 
DECLARE last_day int; 
SET whole_weeks = FLOOR(DATEDIFF(last_date,first_date)/7) ; 
SET first_day = WEEKDAY(first_date) ; 
SET last_day = WEEKDAY(last_date) ; 
IF curr_week_day BETWEEN first_day AND last_day 
      AND last_day > first_day 
      OR (curr_week_day BETWEEN last_day AND first_day 
      AND last_day < first_day ) 
THEN SET days_tot = whole_weeks + 1; 
ELSE SET days_tot = whole_weeks ; 
END IF; 
RETURN days_tot; 
END $$ 
DELIMITER ; 

    SELECT 
     `xx`.`get_weekday` ('2009-01-01', '2009-07-20', 0) as mo, 
     `xx`.`get_weekday` ('2009-01-01', '2009-07-20', 1) as tu, 
     `xx`.`get_weekday` ('2009-01-01', '2009-07-20', 2) as we, 
     `xx`.`get_weekday` ('2009-01-01', '2009-07-20', 3) as th, 
     `xx`.`get_weekday` ('2009-01-01', '2009-07-20', 4) as fr, 
     `xx`.`get_weekday` ('2009-01-01', '2009-07-20', 5) as sa, 
     `xx`.`get_weekday` ('2009-01-01', '2009-07-20', 6) as su; 

基於表查詢

IP:

Weekday count 
2  10 
3   5 


SELECT WEEKDAY(`req_date_time`) AS weekday, COUNT(id) AS id 
FROM `ddd` 
WHERE (
`req_date_time` >= '2014-12-01' 
AND `req_date_time` <= '2014-12-31' 
) 
AND WEEKDAY(`req_date_time`) != '1' 
GROUP BY WEEKDAY(`req_date_time`) 
+0

非常感謝您的支持! – 2016-08-12 21:55:08

0

您也可以使用查詢來做到這一點,但您需要一個涵蓋日期範圍的日期表。無論如何,創建一個用於所有項目的日期表是一種很好的做法。

要創建日期表,您只需生成一長串日期(EXCEL是方便的方法,但還有其他方法)並將它們導入到表中。然後,將這些日期與各種日期函數一起使用以得出「星期幾」,「月」,「年」等,並將所有這些與日期一起保存到表格中,如下所示:

tbl_dates

dates table

陶氏是我的表 '一週中的一天'。然後,您的查詢看起來是這樣的:

SELECT Count(theDate) AS numWeekDays 
FROM tbl_dates 
WHERE theDate >[startDate] And theDate <=[endDate] AND dow <> 1 AND dow <> 7; 

在這種情況下,1和7分別是週日,週六,(這是默認的),當然,你可以窩那到另一個查詢,如果你需要計算這對於許多startDate(s)和endDate(s)。

相關問題