mysql中每月一周的功能

Posted

技术标签:

【中文标题】mysql中每月一周的功能【英文标题】:Function for week of the month in mysql 【发布时间】:2010-10-21 13:49:18 【问题描述】:

我正在寻找一个简单的函数来在 mysql 查询中获取月份中的第几周(而不是一年中最简单的一周)。

我能想到的最好的是:

WEEK(dateField) - WEEK(DATE_SUB(dateField, INTERVAL DAYOFMONTH(dateField)-1 DAY)) + 1

我很想知道我是否在这里重新发明***,是否有更简单、更清洁的解决方案?

【问题讨论】:

【参考方案1】:

AFAIK,每月第一周没有标准。

一年的第一周是包含Jan 4th 的那一周。

你如何定义一个月的第一周?

更新:

您需要像这样重写您的查询:

SELECT  WEEK(dateField, 5) -
        WEEK(DATE_SUB(dateField, INTERVAL DAYOFMONTH(dateField) - 1 DAY), 5) + 1

以便正确处理年份转换,并从Monday 开始。

否则,您的查询没问题。

【讨论】:

我想这可能不是最通用的解决方案,但我需要从星期一开始一周。所以说这个月的 1 号是星期天,那个星期天将被算作第 1 周。如果这是有道理的......【参考方案2】:

报告数据库中有时会使用另一种方法。它是创建一个表,我们称之为 ALMANAC,每个日期有一行(键),并且具有可能对报告目的有用的每个所需的日期属性。

除了月份的星期几列之外,还可以有一列显示日期是否为公司假日,诸如此类。如果贵公司的会计年度从 7 月或其他月份开始,则可以包括每个日期所属的会计年度、会计月、会计周等。

然后,您编写一个程序来凭空填充此表,给定要填充的日期范围。您只需在此程序中包含所有疯狂的日历计算。

然后,当您需要知道某个其他表中某个日期的属性时,您只需进行连接,并使用该列。是的,这又是一次加入。不,这个表没有标准化。但对于某些非常特殊的需求,它仍然是很好的设计。

【讨论】:

【参考方案3】:

我的一周解决方案从星期日开始。

SELECT    ( 1 + ((DATE_FORMAT( DATE_ADD(LAST_DAY( DATE_ADD('2014-07-17',
    INTERVAL -1 MONTH)), INTERVAL 1 DAY),'%w')+1) + 
    (DATE_FORMAT('2014-07-17', '%d')-2) ) DIV 7) "week_of_month";

【讨论】:

【参考方案4】:

(只是为了向未来的读者澄清一下:这个旧问题的答案是由于暗示当前答案不令人满意的赏金而添加的,所以我添加了这个解决方案/定义以及针对各种类型的附加“配置选项”情况。)

Week of month 没有标准定义,但一般的解决方案是以下公式,您可以根据需要进行配置:

select (dayofmonth(dateField) + 6 + (7 - "min_days_for_partial_week") 
        - (weekday(datefield) - "weekday_startofweek" + 7) MOD 7) DIV 7 as week_of_month;

在哪里

"weekday_startofweek" 必须替换为您希望成为一周第一天的工作日(0 = Monday6 = Sunday)。 "min_days_for_partial_week" 是第一周必须算作第 1 周的天数(值 17)。常见值为 1(每月的第一天始终是第 1 周)、4(这类似于“iso week of the year”,其中一年的第一周是包含星期四,至少还有 4 天)和7(第 1 周是第一个完整的一周)。

此公式将返回值 060 表示当前周是没有足够天数计为第 1 周的部分周,而 6 只能在您允许少于 3 天的部分周作为第 1 周时发生。

例子:

如果您一周的第一天是星期一 ("weekday_startofweek" = 0) 并且第一周应该始终是一整周 ("min_days_for_partial_week" = 7),这将简化为

select (dayofmonth(dateField) + 6 - weekday(datefield)) DIV 7 as week_of_month;

例如,对于 2016-06-02,您将获得 0,因为 2016 年 6 月从星期三开始,对于 2016-06-06,您将获得 1,因为这是 2016 年 6 月的第一个星期一。

为了模拟您的公式,一周的第一天始终是第 1 周 ("min_days_for_partial_week" = 1),一周从星期日开始 ("weekday_startofweek" = 6),这将是

select (dayofmonth(dateField) + 12 - (weekday(datefield) + 1) MOD 7) DIV 7 as week_of_month;

虽然您可能想正确地评论一下,以便在 2 年内知道您的常量来自哪里。

【讨论】:

【参考方案5】:

可能已经晚了 12 年,但万一有人还在寻找,我在 bigquery MySQL 中使用这个计算来计算每月的周数。

我将星期一作为计算的第一天

case when 
        (case when EXTRACT(DAYOFWEEK FROM date_add(date(my_date), INTERVAL -(EXTRACT(DAY FROM my_date))+1 day)) = 1 then 7 
                          else EXTRACT(DAYOFWEEK FROM date_add(date(my_date), INTERVAL -(EXTRACT(DAY FROM my_date))+1 day)) -1 end) > 1 then -- check first day of month to decide if it's a complete week (starts on Monday)
                case when EXTRACT(DAY FROM my_date) <= 7 then -- for incomplete week
                    case when 
                            (case when EXTRACT(DAYOFWEEK FROM my_date) = 1 then 7 else EXTRACT(DAYOFWEEK FROM my_date)-1 end)  -  EXTRACT(DAY FROM my_date) =
                                 (case when EXTRACT(DAYOFWEEK FROM date_add(date(my_date), INTERVAL -(EXTRACT(DAY FROM my_date))+1 day)) = 1 then 7 
                                   else EXTRACT(DAYOFWEEK FROM date_add(date(my_date), INTERVAL -(EXTRACT(DAY FROM my_date))+1 day)) -1 end) -1 then 1 -- incomplete week 1
                      else FLOOR(( EXTRACT(DAY FROM my_date) + (case when EXTRACT(DAYOFWEEK FROM date_add(date(my_date), INTERVAL -(EXTRACT(DAY FROM my_date))+1 day)) = 1 then 7
                                                                 else EXTRACT(DAYOFWEEK FROM date_add(date(my_date), INTERVAL -(EXTRACT(DAY FROM my_date))+1 day)) -1 end) -2 )/7)+1 end  -- calculate week based on date
            else FLOOR(( EXTRACT(DAY FROM my_date) + (case when EXTRACT(DAYOFWEEK FROM date_add(date(my_date), INTERVAL -(EXTRACT(DAY FROM my_date))+1 day)) = 1 then 7 
                                                         else EXTRACT(DAYOFWEEK FROM date_add(date(my_date), INTERVAL -(EXTRACT(DAY FROM my_date))+1 day)) -1 end) -2 )/7)+1 end -- calculate week based on date
     else FLOOR((EXTRACT(DAY FROM my_date)-1)/7)+1 -- for complete week
        end

我们的想法是将日差(星期一到该月的第一天)添加到日期,以便正确划分周 > 1

对于第 1 周(

【讨论】:

以上是关于mysql中每月一周的功能的主要内容,如果未能解决你的问题,请参考以下文章

仅跟踪过去一周的帖子浏览量的功能

如何在mysql数据库中取得每月第一天和最后一天之间的数据?

C#中用当前日期算周的若干问题?

如何在mysql中获取日期的一周的第一天?

如何使用任意工作日作为一周的开始从 MySQL 中的日期中提取一周?

JS Date给定时间 获取自然月周的时间轴