NEXT_DAY("01-SEP-95","FRIDAY")
返回下周五的日期,但在 MySQL 中似乎没有出现此函数。有什么替代方案吗?
最佳答案
我将用另一种方法来尝试:
编辑:我后来才意识到相关的 Oracle 函数将字符串作为第二个参数,因此这并不完全符合要求。然而,MySQL 已经友好地将 0 - 6 定义为星期一 - 星期日,无论如何,我在道德上反对使用字符串作为此类事物的参数。字符串可以来自用户输入或者来自数字和字符串值之间的更高级别代码中的另一个映射。为什么不传递一个整数? :)
CREATE FUNCTION `fnDayOfWeekGetNext`(
p_date DATE,
p_weekday TINYINT(3)
) RETURNS date
BEGIN
RETURN DATE_ADD(p_date, INTERVAL p_weekday - WEEKDAY(p_date) + (ROUND(WEEKDAY(p_date) / (p_weekday + WEEKDAY(p_date) + 1)) * 7) DAY);
END
分解决定 INTERVAL
的部分值:
等式的第一部分只是获取指定工作日与指定日期的工作日之间的偏移量:
p_weekday - WEEKDAY(p_date)
如果p_weekday
,这将返回一个正数大于WEEKDAY(p_date)
反之亦然。如果相同则返回零。
ROUND()
段用于确定所请求的星期几 ( p_weekday
) 是否已经出现在相对于指定日期 ( p_date
) 的当前周中。因此,举例来说...
ROUND(WEEKDAY('2019-01-25') / (6 + WEEKDAY('2019-01-25') + 1))
..返回0
,表明本周没有出现星期日 ( 6
),如 2019-01-25
是星期五。同样...
ROUND(WEEKDAY('2019-01-25') / (2 + WEEKDAY('2019-01-25') + 1))
...返回1
因为星期三(2
)已经过去了。请注意,这将返回 0
如果p_weekday
与 p_date
的工作日相同.
然后将该值( 1
或 0
)乘以常数 7
(一周中的天数)。
因此如果 p_weekday
本周已经发生了,它将在偏移量 p_weekday - WEEKDAY(p_date)
上添加 7 ,因为该偏移量将是负数,并且我们想要一个 future 的日期。
如果p_weekday
本周尚未发生,那么我们可以将偏移量添加到当前日期,因为偏移量将是正数。因此,ROUND(...) * 7
部分等于零,本质上被忽略。
我对这种方法的渴望是模拟 IF()
数学上的条件。这同样有效:
RETURN DATE_ADD(p_date, INTERVAL p_weekday - WEEKDAY(p_date) + IF(p_weekday - WEEKDAY(p_date) < 0, 7, 0) DAY);
为了客观性,在每个函数运行几次 1M 迭代时 IF
基于的版本平均比 ROUND
快 4.2% 左右基于版本。
关于mysql - MySQL 可以替代 Oracle 的 NEXT_DAY 函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43870329/