我需要获取“这个星期天”的日期
我该怎么做呢?
我看到了DAYOFWEEK
函数,但那并不是我想要的(在WHERE子句中可能有用)
编辑:
我将问题从我改为了周六改回到原来的星期日,因为我得到了一些有效的星期日答案,这可能会帮助一些人。
我在其他地方(包括SO上)找到了许多其他“本周末”日期的问题和答案。
对我最有用的解决方案是在这里找到的被接受的答案。
我需要获取“这个星期天”的日期
我该怎么做呢?
我看到了DAYOFWEEK
函数,但那并不是我想要的(在WHERE子句中可能有用)
编辑:
我将问题从我改为了周六改回到原来的星期日,因为我得到了一些有效的星期日答案,这可能会帮助一些人。
我在其他地方(包括SO上)找到了许多其他“本周末”日期的问题和答案。
对我最有用的解决方案是在这里找到的被接受的答案。
更新
最好使用curdate()
代替now()
,这样通过date()
进行的最终转换为DATE
类型的操作可以省略。
SELECT curdate() + INTERVAL 6 - weekday(curdate()) DAY;
下周日或者
SET @date = '2014-03-05';
SELECT @date + INTERVAL 6 - weekday(@date) DAY;
对于一个可变的日期,请使用以下语句来获取下一个星期日:
SELECT date(now() + INTERVAL 6 - weekday(now()) DAY);
输出
+-----------------------------------------------+
| date(now() + INTERVAL 6 - weekday(now()) DAY) |
+-----------------------------------------------+
| 2014-04-13 |
+-----------------------------------------------+
说明:
weekday(now())
返回当前星期几(从星期一开始,0代表星期一,6代表星期日)。将当前星期减去6,得到距离下一个星期日剩余的天数作为结果。然后将其加到当前日期上,得到下一个星期日的日期。
如果您希望保持灵活性以适用于任何日期:
SET @date = '2014-03-05';
SELECT date(@date + INTERVAL 6 - weekday(@date) DAY);
输出
+-----------------------------------------------+
| date(@date + INTERVAL 6 - weekday(@date) DAY) |
+-----------------------------------------------+
| 2014-03-09 |
+-----------------------------------------------+
WEEKDAY()
大于所期望的星期几,它会得到该星期几的_前一个_日期,而不是_下一个_日期,对吗?我知道这个解决方案在技术上回答了原始问题,因为它适用于星期日,但是正如你之前提到的,它不能适用于星期六或其他任何一天。例如: SELECT '2019-01-27' + INTERVAL 5 - WEEKDAY('2019-01-27') DAY;
得出的结果是 2019-01-26
。(参考:27号是星期日,26号是星期六。) - undefined SET @THEDAY = 1;
SELECT DATE_ADD(NOW(), INTERVAL if( @THEDAY > WEEKDAY(NOW()) , (@THEDAY - WEEKDAY(NOW())) , (7 - WEEKDAY(NOW())) + @THEDAY) DAY)
我在What is the MySQL alternative to Oracle's NEXT_DAY function?中发布了一个类似的答案,这是对这里提出的问题的更一般性解决方案。下面的解决方案将帮助您获得任何指定的下一个日期(星期日、星期一、星期二、星期三、星期四、星期五或星期六),类似于Oracle中的NEXT_DAY()
函数。
简短版本:
利用DAYOFWEEK()
函数,您可以利用数字值创建一个闭合公式,告诉您要添加多少天。然后,您可以利用DATE_ADD来帮助您移动日期。可能有更简洁的方法,但是您应该能够将其制作成一个函数。
以下是一个Excel公式,您可以使用它来验证所有49个用例:=MOD(MOD(Next-Input, 7)+7,7)
以下是如何将Excel计算转换为SQL的一些示例:
SELECT (((1-DAYOFWEEK('2018-08-15')) % 7)+7) % 7 AS DaysToAddToGetNextSundayFromWednesday
FROM dual; -- 4
SELECT DATE_ADD('2018-08-15', INTERVAL (((1-DAYOFWEEK('2018-08-15')) % 7)+7) % 7 DAY) AS NextSundayFromDate
FROM dual; -- 2018-08-19
如果你计划经常使用上述内容,你可能会想要创建一个函数或存储过程。
详细版本:
多年来,我遇到了这个问题多次。第一次我为所有49种情况创建了一个巨大的case语句。我发现这使得查询变得非常庞大且不干净。我希望有一个更简洁、更简单的解决方案,就像一个封闭的公式一样。下面是我进行的计算细节,以确认上述公式的有效性。我在MySQL 5.7
上进行了测试,如果你使用的是MySQL 8.5,看起来该函数已经内置了(参考:http://www.sqlines.com/mysql/how-to/next_day)。
注意:Excel对于模运算不返回负数结果,而MySQL则会。这就是为什么我们要加上7并再次进行模运算的原因。
DAYOFWEEK()
Sun 1
Mon 2
Tues 3
Wed 4
Thur 5
Fri 6
Sat 7
Input Next Expected Days to Add Formula Result
1 1 0 0
1 2 1 1
1 3 2 2
1 4 3 3
1 5 4 4
1 6 5 5
1 7 6 6
2 1 6 6
2 2 0 0
2 3 1 1
2 4 2 2
2 5 3 3
2 6 4 4
2 7 5 5
3 1 5 5
3 2 6 6
3 3 0 0
3 4 1 1
3 5 2 2
3 6 3 3
3 7 4 4
4 1 4 4
4 2 5 5
4 3 6 6
4 4 0 0
4 5 1 1
4 6 2 2
4 7 3 3
5 1 3 3
5 2 4 4
5 3 5 5
5 4 6 6
5 5 0 0
5 6 1 1
5 7 2 2
6 1 2 2
6 2 3 3
6 3 4 4
6 4 5 5
6 5 6 6
6 6 0 0
6 7 1 1
7 1 1 1
7 2 2 2
7 3 3 3
7 4 4 4
7 5 5 5
7 6 6 6
7 7 0 0
Date()+8-WeekDay(Date())
试一下这个
=IIf(Weekday(Now())=1,DateAdd("d",7,Now()),
IIf(Weekday(Now())=2,DateAdd("d",6,Now()),
IIf(Weekday(Now())=3,DateAdd("d",5,Now()),
IIf(Weekday(Now())=4,DateAdd("d",4,Now()),
IIf(Weekday(Now())=5,DateAdd("d",3,Now()),
IIf(Weekday(Now())=6,DateAdd("d",2,Now()),
IIf(Weekday(Now())=6,DateAdd("d",1,Now()) )))))))
可以将WEEK函数与STR_TO_DATE函数配对使用,实现一个简洁的一行代码:
SELECT STR_TO_DATE(CONCAT(YEAR(NOW()),WEEK(NOW(),1), ' Sunday'), '%X%V %W') as `this Sunday`;
+-------------+
| this Sunday |
+-------------+
| 2014-04-13 |
+-------------+;
'201415 Sunday'
这句话的意思是“在2014年,第15周的星期日”。
以防万一,我在年份边界进行了测试... 目前看起来还不错!
SELECT STR_TO_DATE(CONCAT(YEAR('2014-12-31'),WEEK('2014-12-31',1), ' Sunday'), '%X%V %W') as `this Sunday`;
+-------------+
| this Sunday |
+-------------+
| 2015-01-04 |
+-------------+
接受的答案将在星期日返回上个星期六。 如果你需要下个星期六用于星期日,请使用这个
SELECT
CAST(
Case When weekday(now()) = 6 Then (now() + INTERVAL weekday(now()) DAY)
else (now() + INTERVAL 5 - weekday(now()) DAY)
end
As Date) as saturday