1

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

我正在构建一个支持重复事件的日历。我快完成了,但最后一块是最艰难的。我需要能够支持每 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 个工作日也应该采用该格式。

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

提前致谢。

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

4

3 回答 3

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列来存储星期几整数。

于 2012-10-29T20:09:49.260 回答
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 等创建)。

于 2013-02-21T18:03:00.340 回答
0

最简单的方法是编写一个程序,用您需要的信息填充一个新表。它不需要一张非常大的桌子就能在未来走很长的路。然后只需加入查询中的表即可。

于 2012-10-29T19:28:02.323 回答