【问题标题】:MySQL: find out whether weekday of date is between two weekdays with SQLMySQL:用 SQL 找出日期的工作日是否在两个工作日之间
【发布时间】:2018-12-24 23:12:57
【问题描述】:

我有这个 vb.NET 代码,想在 MySQL 中写一个函数来做同样的事情。

Public Function IsWeekdayTimeInRange(DateToCheck As DateTime, StartDayOfWeek As DayOfWeek,
                                                              EndDayOfWeek As DayOfWeek) As Boolean

    Dim WeekdaysInRange As New List(Of DayOfWeek)
    WeekdaysInRange.Add(StartDayOfWeek)
    Dim i As Integer = StartDayOfWeek
    While i <> EndDayOfWeek
        i += 1
        i = If(i = 7, 0, i)
        WeekdaysInRange.Add(i)
    End While

    Return WeekdaysInRange.Contains(DateToCheck.DayOfWeek)
End Function

我目前在 MySQL 中,但由于我从未编写过 SQL 函数,因此我需要一些帮助。

DELIMITER |
CREATE FUNCTION IS_BETWEEN_WEEKDAYS(d DATETIME, s INT, e INT)
RETURNS BOOLEAN DETERMINISTIC
BEGIN
    DECLARE weekdayToCheck INT;
    DECLARE result BOOLEAN;
    DECLARE i INT;
    SET result = false;
    SET weekdayToCheck = WEEKDAY(d);
    SET i = s;
    WHILE(i <> e) DO

        /* more logic here */

    END WHILE;

    RETURN result;
END; |

DELIMITER ;

编辑:由于我现在了解到 MySQL 具有 Weekday(Monday) = 0,因此我的函数也需要转换为 Weekday(Sunday) = 0,因为我的数据使用该格式。

【问题讨论】:

  • weekdayToCheck &gt; s &amp;&amp; weekdayToCheck &lt; e 应该是一个好的开始

标签: mysql sql weekday


【解决方案1】:

现在可以了。它可能更简洁,但它帮助我思考。

DELIMITER |
CREATE FUNCTION IS_BETWEEN_WEEKDAYS(d DATETIME, s INT, e INT, FirstDayOfWeekIsSunday BOOLEAN)
RETURNS BOOLEAN DETERMINISTIC
BEGIN
    DECLARE weekdayToCheck INT;
    DECLARE result BOOLEAN;
    DECLARE i INT;
    SET result = false;
    SET weekdayToCheck = WEEKDAY(d);
    SET i = s;

    IF FirstDayOfWeekIsSunday = TRUE THEN
        SET weekdayToCheck = weekdayToCheck + 1;
        IF weekdayToCheck = 7 THEN
            SET weekdayToCheck = 0;
        END IF;
    END IF;

    IF weekdayToCheck = s THEN
        SET result = true;
    END IF;

    WHILE(i <> e) DO

        SET i = i + 1;

        IF i = 7 THEN
            SET i = 0;
        END IF;

        IF weekdayToCheck = i THEN 
            SET result = true;
        END IF;

    END WHILE;

    RETURN result;
END; |

DELIMITER ;

编辑:修复了循环中的顺序问题。还添加了处理se 的选项,如果他们假设一周从星期日开始。 编辑:测试了上述内容并且可以正常工作。还可以创建一个函数来检查日期时间是否在星期二下午 3 点和星期四凌晨 2 点之间。

DELIMITER |
CREATE FUNCTION IS_BETWEEN_WEEKDAYS_AND_TIME(d DATETIME, s INT, starttime TIME, e INT, endtime TIME, FirstDayOfWeekIsSunday BOOLEAN)
RETURNS BOOLEAN DETERMINISTIC
BEGIN
    DECLARE weekdayToCheck INT;
    DECLARE result BOOLEAN;
    DECLARE i INT;
    DECLARE dTime TIME;
    SET result = false;
    SET weekdayToCheck = WEEKDAY(d);
    SET i = s;
    SET dTime = DATE_FORMAT(d, '%H:%i:%s');

    IF FirstDayOfWeekIsSunday = TRUE THEN
        SET weekdayToCheck = weekdayToCheck + 1;
        IF weekdayToCheck = 7 THEN
            SET weekdayToCheck = 0;
        END IF;
    END IF;

    IF weekdayToCheck = s THEN 
        IF ((weekdayToCheck = s AND dTime > starttime) OR (weekdayToCheck = e AND dTime < endtime) OR (weekdayToCheck <> s AND weekdayToCheck <> e)) THEN
            SET result = true;
        END IF;
    END IF;

    WHILE(i <> e) DO

        SET i = i + 1;

        IF i = 7 THEN
            SET i = 0;
        END IF;

        IF weekdayToCheck = i THEN 
            IF ((weekdayToCheck = s AND dTime > starttime) OR (weekdayToCheck = e AND dTime < endtime) OR (weekdayToCheck <> s AND weekdayToCheck <> e)) THEN
                SET result = true;
            END IF;
        END IF;

    END WHILE;

    RETURN result;
END; |

DELIMITER ;

【讨论】:

    【解决方案2】:

    考虑从星期一开始的一周。希望这会有所帮助:

    DELIMITER |
    CREATE FUNCTION IS_BETWEEN_WEEKDAYS(d DATETIME, s INT, e INT)
    RETURNS BOOLEAN DETERMINISTIC
    BEGIN
      DECLARE weekdayToCheck INT;
      DECLARE result TINYINT(1);
      SET weekdayToCheck =  WEEKDAY(d);
      SET result = 0;
      IF(weekdayToCheck > s AND weekdayToCheck < e) THEN
        SET result = 1;
      ELSEIF (s > e AND weekdayToCheck < s AND weekdayToCheck < e) THEN
        SET result = 1;
      END IF;
    
    RETURN result;
    END; |
    
    DELIMITER ;
    

    【讨论】:

    • 谢谢,但问题与 Joakims 的回答相同。在那里看到我的评论。没有办法绕过 while 循环。
    • 抱歉,这不起作用。我已经用足够的测试数据测试了这里给出的所有答案。不管怎么说,还是要谢谢你。顺便说一句,-1SET weekdayToCheck = DAYOFWEEK(d) - 1; 中做什么
    • 在哪种情况下会失败? “-1”,因此第 1 天从星期一开始。 DAYOFWEEK 从 [ sun(1) - sat(7) ] 开始。您可以相应地更改它。
    • -1 没有解决从星期日开始的一周的问题。首先,您必须添加 1,其次,即使在 MySQL 中,序列也以 0 开头并且永远不会以 7 结尾,但这意味着如果您以 7 结尾(或者在您的情况下为 -1),您必须将其转换(请参阅我的答案) .在我的测试查询中,每个函数都有一列,而你的总是返回 0
    • eg: For tadays date [select DAYOFWEEK('2018-07-17');] 返回值3。由于今天是一周的第二天,我们将减去1。请给我此函数失败的日期和星期几。
    【解决方案3】:

    不确定你对“之间”的定义是什么,但在这里我使用了大于和小于

    CREATE FUNCTION IS_BETWEEN_WEEKDAYS(d DATETIME, s INT, e INT)
    RETURNS BOOLEAN DETERMINISTIC
    BEGIN
        DECLARE weekdayToCheck INT;
        DECLARE result INT;
        SET weekdayToCheck = WEEKDAY(d);
        SET result = 0;
    
        IF (s < e) THEN 
           IF  (weekdayToCheck > s AND weekdayToCheck < e) THEN SET result = 1;
           END IF;
        END IF;
    
        IF (s > e) THEN
           IF (weekdayToCheck > s OR weekdayToCheck < e) THEN SET result = 1;
           END IF;        
        END IF;
    
        RETURN result; 
    END;
    

    也许所有的 if/else 子句都可以缩短一些。

    【讨论】:

    • 不是那么简单:星期天是 0,星期六是 6。如果你想测试你的一天是否在周末,这是行不通的。
    • @penCsharpener 不,在 MySql 中 0(零)是星期一,所以这应该可以正常工作,doc。当然,如果你想有不同的定义,那么你需要调整代码。
    • 是的,必须这样做,因为我必须检查的一些值保存在 .NET 序列中。这使得它更加复杂。但是问题仍然存在:即。检查星期一是否在星期六和星期二之间:0 &gt; 5 &amp;&amp; 0 &lt; 1 = false
    • @penCsharpener,当然可以。对此感到抱歉,请参阅我的更新答案。
    猜你喜欢
    • 1970-01-01
    • 2020-04-03
    • 1970-01-01
    • 1970-01-01
    • 2021-06-02
    • 2020-11-20
    • 2010-09-20
    • 2023-03-09
    • 2015-07-21
    相关资源
    最近更新 更多