MariaDB 一周开始日期和周数 1 到 52
MariaDB start of week date & week number 1 to 52
我已经编写了一个存储过程来从日期中获取周数,它还returns周开始的日期以及周数和年份。
我知道 'WEEK' 函数,但是这并没有给我一周开始的日期,而且我不知道在给定周和年的情况下执行此操作的函数.
问题是:
给定周数,如何在一周开始时获得 'date' ?一周的开始作为日期索引传入,0 = 星期日,1 = 星期一等
我当前的功能并不总是有效,如果一周的第一天是星期一,那么星期天就会进入下一周,而不是我希望的同一周的结束。
使用Sequence引擎。您可以根据需要调整以下示例:
MariaDB [_]> SHOW ENGINES\G
.
.
.
*************************** 3. row ***************************
Engine: SEQUENCE
Support: YES
Comment: Generated tables filled with sequential values
Transactions: YES
XA: NO
Savepoints: YES
.
.
.
MariaDB [_]> SET @`year` := 2016,
-> @`mode` := 1,
-> @`week` := 23;
Query OK, 0 rows affected (0.00 sec)
MariaDB [_]> SELECT
-> `der`.`date`,
-> `der`.`week`,
-> `der`.`year`
-> FROM (
-> SELECT
-> `der`.`date`,
-> WEEK(`der`.`date`, @`mode`) `week`,
-> YEAR(`der`.`date`) `year`
-> FROM (
-> SELECT
-> DATE_ADD(CONCAT(@`year`, '-01-01'), INTERVAL `s`.`seq` DAY) `date`
-> FROM
-> seq_0_to_365 `s`
-> ) `der`
-> ) `der`
-> WHERE
-> `der`.`week` = @`week` AND
-> `der`.`year` = @`year`;
+------------+------+------+
| date | week | year |
+------------+------+------+
| 2016-06-06 | 23 | 2016 |
| 2016-06-07 | 23 | 2016 |
| 2016-06-08 | 23 | 2016 |
| 2016-06-09 | 23 | 2016 |
| 2016-06-10 | 23 | 2016 |
| 2016-06-11 | 23 | 2016 |
| 2016-06-12 | 23 | 2016 |
+------------+------+------+
7 rows in set (0.01 sec)
解决了,我重写了存储过程:
exitProc:BEGIN
#--
# Procedure:
# weekFromDate
#
# Parameters:
# vcCompKey, the key associated with the company
# dtDate, the date to translate
# dtOutSOW, returned start of week date
# siOutWeek, returned week number
# siOutYear, returned year
#--
DECLARE siDIY SMALLINT; #Day in year
DECLARE siFDOW SMALLINT; #First day of week
DECLARE siGoBack SMALLINT; #Flag used to check for last year
DECLARE siRmonth SMALLINT; #Reference Month
DECLARE siRyear SMALLINT; #Reference Year
DECLARE dtSOY DATE; #Date of start of year
DECLARE vcFMDOY VARCHAR(12);#First month and day of year
DECLARE vcFDOW VARCHAR(12);#First day of the week
DECLARE vcDYSOW VARCHAR(80);#Days of week
#Get the first day of the week for the specified company
SET vcFDOW = vcGetParamValue(vcCompKey, 'Var:First day of week');
IF (vcFDOW IS NULL) THEN
#No entry found, abort!
LEAVE exitProc;
END IF;
#Get the first month and day of the year for the specified company
SET vcFMDOY = vcGetParamValue(vcCompKey, 'Var:First day of year');
IF (vcFMDOY IS NULL) THEN
#No entry found, abort!
LEAVE exitProc;
END IF;
#Set-up days of week
SET vcDYSOW = 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday';
#Get the first day of the week index base 1
SET siFDOW = FIND_IN_SET(LOWER(vcFDOW), LOWER(vcDYSOW)) - 1;
#Get the reference month and year
SET siRmonth = MONTH(dtDate);
SET siRyear = YEAR(dtDate);
SET dtSOY = DATE(CONCAT(siRyear, '/', vcFMDOY));
#Calculate the start of week date
SET dtOutSOW = DATE_SUB(dtDate, INTERVAL (DAYOFWEEK(dtDate) - siFDOW) DAY) + 1;
#Calculate the day in year
SET siDIY = DATEDIFF(dtOutSOW, dtSOY);
#Do we need to go back to the end of the previous year?
SET siGoBack = YEAR(dtDate) - YEAR(dtOutSOW);
IF siGoBack < 0 Or siDIY < 0 Or dtDate < dtOutSOW THEN
#Yes
IF YEAR(dtOutSOW) = YEAR(dtDate) THEN
SET dtOutSOW = DATE_SUB(dtOutSOW, INTERVAL 7 DAY);
END IF;
SET dtSOY = DATE(CONCAT(YEAR(dtOutSOW), '/', vcFMDOY));
SET siDIY = DATEDIFF(dtOutSOW, dtSOY);
END IF;
#Calculate the week no. and year
SET siOutWeek = (siDIY / 7) + 1;
SET siOutYear = YEAR(dtOutSOW);
END
这个例程确实使用了我数据库中的其他表,并允许公司有不同的开始年份。
作为测试,我会找到本周的开始,首先注意:
mysql> SELECT NOW(), WEEK(NOW());
+---------------------+-------------+
| NOW() | WEEK(NOW()) |
+---------------------+-------------+
| 2016-06-18 12:10:58 | 24 |
+---------------------+-------------+
那么这就是函数的核心:
mysql> SELECT '2016-01-01'
+ INTERVAL 7*24
- DAYOFWEEK('2016-01-01')
+ 1 DAY;
+----------------------------------------------------------------+
| '2016-01-01' + INTERVAL 7*24 - DAYOFWEEK('2016-01-01') + 1 DAY |
+----------------------------------------------------------------+
| 2016-06-12 |
+----------------------------------------------------------------+
'2016-01-01'
是相关年份的开始。
24
是 WEEK()
号。
+ 1 DAY
是为了补偿一周的开始。
还需要做一些其他事情来处理您选择一周从哪一天开始的选项。
我也在研究这个问题。但我偶然发现了一些同样有效的 mysql 代码。它基本上是根据星期几减去天数。即如果日期是星期三 (4),您知道日期是 1-4=-3 天前。
这个怎么样:
# with Sunday being the start of the week:
select convert(date_add(now(), interval(1-dayofweek(now())) day), date) as WeekStartDate
select convert(date_add(now(), interval(7-dayofweek(now())) day), date) as WeekEndDate
# with Monday being the start of the week:
select convert(date_add(now(), interval(2-dayofweek(now())) day), date) as WeekStartDate
select convert(date_add(now(), interval(8-dayofweek(now())) day), date) as WeekEndDate
信用:
How do I get the first day of the week of a date in mysql?
对user1014010的回答进行了一些更正。当一周从星期一开始时,您将收到下周星期日的日期。这是我的更正:
SELECT DATE(DATE_ADD(NOW(), INTERVAL -((5 + DAYOFWEEK(NOW())) % 7) DAY)) AS WeekStartDate
我已经编写了一个存储过程来从日期中获取周数,它还returns周开始的日期以及周数和年份。
我知道 'WEEK' 函数,但是这并没有给我一周开始的日期,而且我不知道在给定周和年的情况下执行此操作的函数.
问题是:
给定周数,如何在一周开始时获得 'date' ?一周的开始作为日期索引传入,0 = 星期日,1 = 星期一等
我当前的功能并不总是有效,如果一周的第一天是星期一,那么星期天就会进入下一周,而不是我希望的同一周的结束。
使用Sequence引擎。您可以根据需要调整以下示例:
MariaDB [_]> SHOW ENGINES\G
.
.
.
*************************** 3. row ***************************
Engine: SEQUENCE
Support: YES
Comment: Generated tables filled with sequential values
Transactions: YES
XA: NO
Savepoints: YES
.
.
.
MariaDB [_]> SET @`year` := 2016,
-> @`mode` := 1,
-> @`week` := 23;
Query OK, 0 rows affected (0.00 sec)
MariaDB [_]> SELECT
-> `der`.`date`,
-> `der`.`week`,
-> `der`.`year`
-> FROM (
-> SELECT
-> `der`.`date`,
-> WEEK(`der`.`date`, @`mode`) `week`,
-> YEAR(`der`.`date`) `year`
-> FROM (
-> SELECT
-> DATE_ADD(CONCAT(@`year`, '-01-01'), INTERVAL `s`.`seq` DAY) `date`
-> FROM
-> seq_0_to_365 `s`
-> ) `der`
-> ) `der`
-> WHERE
-> `der`.`week` = @`week` AND
-> `der`.`year` = @`year`;
+------------+------+------+
| date | week | year |
+------------+------+------+
| 2016-06-06 | 23 | 2016 |
| 2016-06-07 | 23 | 2016 |
| 2016-06-08 | 23 | 2016 |
| 2016-06-09 | 23 | 2016 |
| 2016-06-10 | 23 | 2016 |
| 2016-06-11 | 23 | 2016 |
| 2016-06-12 | 23 | 2016 |
+------------+------+------+
7 rows in set (0.01 sec)
解决了,我重写了存储过程:
exitProc:BEGIN
#--
# Procedure:
# weekFromDate
#
# Parameters:
# vcCompKey, the key associated with the company
# dtDate, the date to translate
# dtOutSOW, returned start of week date
# siOutWeek, returned week number
# siOutYear, returned year
#--
DECLARE siDIY SMALLINT; #Day in year
DECLARE siFDOW SMALLINT; #First day of week
DECLARE siGoBack SMALLINT; #Flag used to check for last year
DECLARE siRmonth SMALLINT; #Reference Month
DECLARE siRyear SMALLINT; #Reference Year
DECLARE dtSOY DATE; #Date of start of year
DECLARE vcFMDOY VARCHAR(12);#First month and day of year
DECLARE vcFDOW VARCHAR(12);#First day of the week
DECLARE vcDYSOW VARCHAR(80);#Days of week
#Get the first day of the week for the specified company
SET vcFDOW = vcGetParamValue(vcCompKey, 'Var:First day of week');
IF (vcFDOW IS NULL) THEN
#No entry found, abort!
LEAVE exitProc;
END IF;
#Get the first month and day of the year for the specified company
SET vcFMDOY = vcGetParamValue(vcCompKey, 'Var:First day of year');
IF (vcFMDOY IS NULL) THEN
#No entry found, abort!
LEAVE exitProc;
END IF;
#Set-up days of week
SET vcDYSOW = 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday';
#Get the first day of the week index base 1
SET siFDOW = FIND_IN_SET(LOWER(vcFDOW), LOWER(vcDYSOW)) - 1;
#Get the reference month and year
SET siRmonth = MONTH(dtDate);
SET siRyear = YEAR(dtDate);
SET dtSOY = DATE(CONCAT(siRyear, '/', vcFMDOY));
#Calculate the start of week date
SET dtOutSOW = DATE_SUB(dtDate, INTERVAL (DAYOFWEEK(dtDate) - siFDOW) DAY) + 1;
#Calculate the day in year
SET siDIY = DATEDIFF(dtOutSOW, dtSOY);
#Do we need to go back to the end of the previous year?
SET siGoBack = YEAR(dtDate) - YEAR(dtOutSOW);
IF siGoBack < 0 Or siDIY < 0 Or dtDate < dtOutSOW THEN
#Yes
IF YEAR(dtOutSOW) = YEAR(dtDate) THEN
SET dtOutSOW = DATE_SUB(dtOutSOW, INTERVAL 7 DAY);
END IF;
SET dtSOY = DATE(CONCAT(YEAR(dtOutSOW), '/', vcFMDOY));
SET siDIY = DATEDIFF(dtOutSOW, dtSOY);
END IF;
#Calculate the week no. and year
SET siOutWeek = (siDIY / 7) + 1;
SET siOutYear = YEAR(dtOutSOW);
END
这个例程确实使用了我数据库中的其他表,并允许公司有不同的开始年份。
作为测试,我会找到本周的开始,首先注意:
mysql> SELECT NOW(), WEEK(NOW());
+---------------------+-------------+
| NOW() | WEEK(NOW()) |
+---------------------+-------------+
| 2016-06-18 12:10:58 | 24 |
+---------------------+-------------+
那么这就是函数的核心:
mysql> SELECT '2016-01-01'
+ INTERVAL 7*24
- DAYOFWEEK('2016-01-01')
+ 1 DAY;
+----------------------------------------------------------------+
| '2016-01-01' + INTERVAL 7*24 - DAYOFWEEK('2016-01-01') + 1 DAY |
+----------------------------------------------------------------+
| 2016-06-12 |
+----------------------------------------------------------------+
'2016-01-01'
是相关年份的开始。
24
是 WEEK()
号。
+ 1 DAY
是为了补偿一周的开始。
还需要做一些其他事情来处理您选择一周从哪一天开始的选项。
我也在研究这个问题。但我偶然发现了一些同样有效的 mysql 代码。它基本上是根据星期几减去天数。即如果日期是星期三 (4),您知道日期是 1-4=-3 天前。
这个怎么样:
# with Sunday being the start of the week:
select convert(date_add(now(), interval(1-dayofweek(now())) day), date) as WeekStartDate
select convert(date_add(now(), interval(7-dayofweek(now())) day), date) as WeekEndDate
# with Monday being the start of the week:
select convert(date_add(now(), interval(2-dayofweek(now())) day), date) as WeekStartDate
select convert(date_add(now(), interval(8-dayofweek(now())) day), date) as WeekEndDate
信用: How do I get the first day of the week of a date in mysql?
对user1014010的回答进行了一些更正。当一周从星期一开始时,您将收到下周星期日的日期。这是我的更正:
SELECT DATE(DATE_ADD(NOW(), INTERVAL -((5 + DAYOFWEEK(NOW())) % 7) DAY)) AS WeekStartDate