如何在MySQL查询中获取给定月份的第N个工作日的日期?

时间:2012-10-29 19:09:26

标签: mysql date weekday

我已经搜索了答案,虽然我发现在线回答了类似的问题,但我一直无法将它们用于我的目的。我需要帮助。

我正在构建支持重复活动的日历。我差不多完成了,但最后一块是最难的。我需要能够支持每Y个月的第N个X发生的事件,其中X是给定的工作日,Y是几个月。

我已经找出了“每Y个月”部分(这是下面查询部分中第二行到最后一行)。我只需要得到“第N个工作日”。

我找到了一个有人创建的PHP脚本声称可以解决这个问题,我计划使用它,但后来我意识到这必须完全在MySQL查询中完成,因为指定哪个工作日获取日期的值是db记录的一部分,我不能让它们在主查询之外使用。

以下是查询的一部分,以便您了解我的目标:

WHEN event_recurring_pattern_type = 'monthly' AND event_recurring_monthly_type = 'dayxofeveryxmonths' THEN
    MOD(PERIOD_DIFF(CONCAT(event_date_year,event_date_month), CONCAT('$date_year','$date_month')), event_recurring_monthly_dayofeveryxmonths) = 0
    AND event_recurring_monthly_dayx = '$date_day'

WHEN event_recurring_pattern_type = 'monthly' AND event_recurring_monthly_type = 'thexweekdayofeveryxmonths' THEN
    MOD(PERIOD_DIFF(CONCAT(event_date_year,event_date_month), CONCAT('$date_year','$date_month')), event_recurring_monthly_dayofeveryxmonths) = 0
    AND '$date_timestamp' = {the date of the Nth weekday of $date_month}

最后一行应该将日历的当前输出日期(因为它一次构建一个日历)与输出过程中我们所处的任何月份的第N个工作日的日期进行比较。当它们匹配时,该事件将输出到日历上。

在这种情况下,$ date_timestamp是'YYYY-MM-DD'格式的当前输出日期,因此我得到日期的第N个工作日也应采用该格式。

如果我没有提供足够的信息,或者在其他地方得到了充分的答复,请告诉我。我之前的一个问题是“关闭”,因为有些人认为它太模糊或者没有给出足够的信息,即使我提供了大量与我的问题相关的信息,但仍然得到了一个完全可以接受的答案来解决我的问题。如果有必要,请给我一个改进问题的机会,然后再采取消极行动。

提前致谢。

哦,是的,如果可以进一步创建这个以选择性地获得给定月份的LAST指定工作日,那就更好了。 PHP脚本就是这样做的,但就像我说的那样,这次我不能用PHP做到这一点。

3 个答案:

答案 0 :(得分:1)

使用 DAYOFWEEK()

WHEN event_recurring_pattern_type = 'monthly'
 AND event_recurring_monthly_type = 'thexweekdayofeveryxmonths'
THEN MOD(
       PERIOD_DIFF(
         CONCAT(event_date_year,event_date_month),
         CONCAT('$date_year','$date_month')
       ), event_recurring_monthly_dayofeveryxmonths
     ) = 0
 AND DAYOFWEEK('$date_timestamp') = event_recurring_monthly_dayofweek

以上假设添加了event_recurring_monthly_dayofweek列,但您可以轻松地重复使用event_recurring_monthly_dayx列来存储星期几整数。

答案 1 :(得分:0)

最简单的方法是编写一个程序,用您需要的信息填充新表。它不需要一个非常大的表来走很长一段路。然后只需加入查询中的表格。

答案 2 :(得分:0)

我将尝试这个(尚未在现场证明):

 SET @target = DATE('2013-06-15');
SELECT  1 + ( 
 IF( MONTH(DATE_SUB( @target, INTERVAL  7 DAY)) = MONTH(@target), 1, 0) +
 IF( MONTH(DATE_SUB( @target, INTERVAL 14 DAY)) = MONTH(@target), 1, 0) +
 IF( MONTH(DATE_SUB( @target, INTERVAL 21 DAY)) = MONTH(@target), 1, 0) +
 IF( MONTH(DATE_SUB( @target, INTERVAL 28 DAY)) = MONTH(@target), 1, 0) ) AS nth_weekday_of_month;

看起来相对较快,但您可以随时使用此功能创建预先填充的表格(几年后,或由crons等创建)。