我正在寻找一个简单的函数来获取mysql查询中的一周(而不是一年中的简单星期)。
我能想到的最好的是:
WEEK(dateField) - WEEK(DATE_SUB(dateField, INTERVAL DAYOFMONTH(dateField)-1 DAY)) + 1
我想知道我是否在这里重新发明轮子,是否有更简单,更清洁的解决方案?
答案 0 :(得分:15)
AFAIK,一个月的第一周没有标准。
一年中的第一周是包含Jan 4th
的一周。
您如何定义月份的第一周?
<强>更新强>
您需要像这样重写您的查询:
SELECT WEEK(dateField, 5) -
WEEK(DATE_SUB(dateField, INTERVAL DAYOFMONTH(dateField) - 1 DAY), 5) + 1
以便正确处理年度转换,并且周期从Monday
开始。
否则,您的查询没问题。
答案 1 :(得分:8)
有一种替代方法有时会用于报告数据库。它是创建一个表,我们称之为ALMANAC,每个日期(密钥)有一行,并且具有可能对报告有用的日期的所有必需属性。
除了每月的一周列之外,还可能有一个列,表明日期是否是公司假期,以及类似的事情。如果您的公司的财政年度从7月或其他月份开始,您可以包括每个日期所属的会计年度,会计月度,会计周等。
然后你写了一个程序,凭空填充这个表,给出了一系列日期。您只需在此程序中包含一次所有疯狂日历计算。
然后,当您需要知道某个其他表中某个日期的属性时,您只需要进行连接,然后使用该列。是的,这是另一个加入。不,这个表没有规范化。但对于某些非常具体的需求,它仍然是一个很好的设计。
答案 2 :(得分:1)
(只是为了向未来的读者澄清:这个旧问题的答案之所以被添加,是因为暗示当前的答案并不令人满意,所以我添加了这个解决方案/定义以及其他&#34;配置选项& #34;适用于各种情况。)
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
(这类似于&#34;一年中的iso周&#34;,第一周的第一周年份是包含星期四的星期,因此至少有4天),7
(第1周是第一个完整的星期)。此公式会将值0
返回到6
。 0
表示当前周是一个部分周,没有足够的天数计算为第1周,而6
只能在您允许少于3天的部分周数时才会发生第1周。
示例:
如果您一周的第一天是星期一("weekday_startofweek" = 0
)而第1周应该是整周("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年内正确评论你的常数来自哪里。
答案 3 :(得分:0)
一周的解决方案从周日开始。
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";