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 = Monday
、6 = Sunday
)。
"min_days_for_partial_week"
是第一周必须算作第 1 周的天数(值 1
到 7
)。常见值为 1
(每月的第一天始终是第 1 周)、4
(这类似于“iso week of the year”,其中一年的第一周是包含星期四,至少还有 4 天)和7
(第 1 周是第一个完整的一周)。
此公式将返回值 0
到 6
。 0
表示当前周是没有足够天数计为第 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数据库中取得每月第一天和最后一天之间的数据?