我要尝试的是设置时间间隔的开始(如果未正确将其设置为存储过程的话)。但是,它以某种方式不能很好地工作。
这是我的代码:
CREATE PROCEDURE intervals_generator (IN start DATETIME, IN ending DATETIME, IN intervalis INT)
BEGIN
-- temp values
DECLARE next_date DATETIME;
-- result temp values
DECLARE start_temp DATETIME;
DECLARE ending_temp DATETIME;
-- date formatting variables
DECLARE year CHAR(20);
DECLARE month CHAR(20);
DECLARE day CHAR(20);
DECLARE new_start CHAR(20);
-- SET starting date if is incorrect DATE_FORMAT(NOW(), '%d %m %Y')
SET year := DATE_FORMAT(start, '%Y');
SET month := DATE_FORMAT(start, '%c');
SET day := DATE_FORMAT(start, '%e');
IF intervalis = '1_day' THEN
BEGIN
SET new_start := year+' '+month+' '+day+' 00:00:00';
END;
ELSEIF intervalis = '1_month' THEN
BEGIN
SET new_start := year+' '+month+' 1 00:00:00';
END;
ELSEIF intervalis = '1_quarter' THEN
BEGIN
IF MONTH(start) IN (2, 3) THEN
SET month := 1;
ELSEIF MONTH(start) IN (5, 6) THEN
SET month := 4;
ELSEIF MONTH(start) IN (8, 9) THEN
SET month := 7;
ELSEIF MONTH(start) IN (11, 12) THEN
SET month := 10;
END IF;
SET new_start := year+' '+month+' 1 00:00:00';
END;
ELSEIF intervalis = '1_year' THEN
BEGIN
SET new_start := year+' 1 1 00:00:00';
END;
END IF;
SET start := STR_TO_DATE(new_start, '%Y %c %e %h:%i:%s');
SELECT year, month, day, start;
DROP TEMPORARY TABLE IF EXISTS intervals_result;
END//
DELIMITER ;
我尝试了许多不同的格式设置和功能,但输出仍然错误,如下所示:
mysql> CALL intervals_generator('2013-02-01 00:00:00', '2015-12-31 00:00:00', '1_year');
+------+-------+------+---------------------+
| year | month | day | start |
+------+-------+------+---------------------+
| 2013 | 2 | 1 | 2016-00-00 00:00:00 |
+------+-------+------+---------------------+
1 row in set (0.02 sec)
Query OK, 0 rows affected, 1 warning (0.02 sec)
我真的不明白为什么输出是“ 2016-00-00”而不是“ 2013-01-01”。年,月和日变量定义为CHAR,并且从日期时间提取它们的函数也应返回CHAR。而且功能STR_TO_DATE也应该采用CHAR格式,因此对我来说是个谜。
如果有人有什么想法,请给我提示。
如果您使用DATE
s而不是字符串来工作,则可以使用MySQL的日期函数和运算符,并使所有内容都变得更加简单...但是不要太简单,因为这是MySQL。
MySQL和日期的问题在于它的日期功能是一个真正的混搭,有时与DATE
s一起使用,有时与字符串一起使用,有时与整数一起使用,并且缺少基本功能。它缺少设置日期的简单功能。没有将MONTH
a的部分更改DATE
为2月的功能。甚至没有一种从年,月和日中确定日期的好方法,您得到的最接近的东西MAKEDATE()
需要一年和一年中的某一天(?!)。幸运的是,DATE
MySQL中的s响应数学运算,这比弄乱字符串要好。
例如,如果您有,2013-02-12
并且想要2013-02-01
使用,首先只用年份创建一个新日期MAKEDATE
,然后添加月份部分。
-- 2013-01-01
SET new_date := MAKEDATE(YEAR(old_date), 1);
-- 2013-02-01
-- Since MONTH returns from 1 to 12, you need to take away one.
SET new_date := new_date + (INTERVAL MONTH(old_date) - 1) MONTH;
切掉所有未使用的变量,更改日期数学,并使用CASE语句代替大型的IF / ELSE链后,我们得到以下信息:
CREATE PROCEDURE intervals_generator (IN start_date DATE, IN intervals TEXT)
BEGIN
DECLARE new_start DATE;
CASE intervals
WHEN '1_day' THEN
-- Nothing to do, DATE has already truncated the time portion.
SET new_start := start_date;
WHEN '1_month' THEN
-- Set to the year and month of the start date
SET new_start := MAKEDATE(YEAR(start_date), 1) + INTERVAL (MONTH(start_date) - 1) MONTH;
WHEN '1_quarter' THEN
BEGIN
-- Set to the year and month of the start date
SET new_start := MAKEDATE(YEAR(start_date), 1) + INTERVAL (MONTH(start_date) - 1) MONTH;
-- Subtract the necessary months for the beginning of the quarter
SET new_start := new_start - INTERVAL (MONTH(new_start) - 1) % 3 MONTH;
END;
WHEN '1_year' THEN
-- Set the date to the first day of the year
SET new_start := MAKEDATE(YEAR(start_date), 1);
END CASE;
SELECT new_start;
END//
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句