在MySQL中更改日期时间值
我想做的是设置时间间隔的开始,若并没有正确地设置到存储过程中。然而,不知何故,它并没有起到很好的作用 这是我的代码:在MySQL中更改日期时间值,mysql,sql,datetime,Mysql,Sql,Datetime,我想做的是设置时间间隔的开始,若并没有正确地设置到存储过程中。然而,不知何故,它并没有起到很好的作用 这是我的代码: CREATE PROCEDURE intervals_generator (IN start DATETIME, IN ending DATETIME, IN intervalis INT) BEGIN -- temp values DECLARE next_date DATETIME; -- result temp values DECLAR
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,从datetime提取它们的函数也应该返回CHAR。函数STR_TO_DATE也应该采用CHAR格式,所以对我来说这是个谜
如果有人有什么想法,请给我一个提示。如果你在中而不是字符串中工作,你可以利用MySQL的日期,让一切变得更简单。。。但不要太简单,因为这是MySQL
MySQL和dates的问题在于它的日期功能是一个真正的mish mash,有时使用date
s,有时使用字符串,有时使用整数,并且缺少基本功能。它缺少一个简单的函数来设置日期;没有将日期的月份
部分更改为2月份的功能。甚至没有一个很好的方法可以根据年、月、日来确定日期,你得到的最接近的东西是哪一年、哪一天(?)。这总比摆弄琴弦好
例如,如果您有2013-02-12
并且想要2013-02-01
您必须首先使用年份创建一个新日期,然后添加月份部分
-- 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;
剔除所有未使用的变量,更改为最新数学,并使用而不是大的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//
这句话没有达到你的预期:
SET new_start := year+' '+month+' '+day+' 00:00:00';
在MySQL中,+
操作符执行加法。就是这样,不是串联
我认为你打算:
SET new_start := concat(year, ' ', month, ' ', day, ' 00:00:00');
我还没有研究其余的逻辑,看它是否有意义,但这是一个突出的问题。您可以使用内置的,而不是从容易出错的部分(串联)切片和构建新的日期:
SET @date = '2013-05-03 10:05:00';
SELECT CAST(@date AS DATETIME) AS Date,
DATE_FORMAT(@date ,'%Y-01-01 00:00:00') AS Year_Allign,
CASE EXTRACT(QUARTER FROM @date)
WHEN 1 THEN DATE_FORMAT(@date ,'%Y-01-01 00:00:00')
WHEN 2 THEN DATE_FORMAT(@date ,'%Y-04-01 00:00:00')
WHEN 3 THEN DATE_FORMAT(@date ,'%Y-07-01 00:00:00')
WHEN 4 THEN DATE_FORMAT(@date ,'%Y-10-01 00:00:00')
ELSE NULL END AS Quarter_Allign,
DATE_FORMAT(@date ,'%Y-%m-01 00:00:00') AS Month_Allign,
DATE_FORMAT(@date ,'%Y-%m-%d 00:00:00') AS Day_Allign;
SET @date = '2013-05-03 10:05:00';
SET @allign = '1_QUARTER';
SELECT
CAST(@date AS DATETIME) AS Date,
CASE @allign
WHEN '1_YEAR' THEN DATE_FORMAT(@date ,'%Y-01-01 00:00:00')
WHEN '1_QUARTER' THEN (CASE EXTRACT(QUARTER FROM @date)
WHEN 1 THEN DATE_FORMAT(@date ,'%Y-01-01 00:00:00')
WHEN 2 THEN DATE_FORMAT(@date ,'%Y-04-01 00:00:00')
WHEN 3 THEN DATE_FORMAT(@date ,'%Y-07-01 00:00:00')
WHEN 4 THEN DATE_FORMAT(@date ,'%Y-10-01 00:00:00')
ELSE NULL END)
WHEN '1_MONTH' THEN DATE_FORMAT(@date ,'%Y-%m-01 00:00:00')
WHEN '1_DAY' THEN DATE_FORMAT(@date ,'%Y-%m-%d 00:00:00')
ELSE NULL
END AS Alligned;
SET @date = '2013-05-03 10:05:00';
SELECT CAST(@date AS DATETIME) AS Date,
DATE_FORMAT(@date ,'%Y-01-01 00:00:00') AS Year_Allign,
CASE EXTRACT(QUARTER FROM @date)
WHEN 1 THEN DATE_FORMAT(@date ,'%Y-01-01 00:00:00')
WHEN 2 THEN DATE_FORMAT(@date ,'%Y-04-01 00:00:00')
WHEN 3 THEN DATE_FORMAT(@date ,'%Y-07-01 00:00:00')
WHEN 4 THEN DATE_FORMAT(@date ,'%Y-10-01 00:00:00')
ELSE NULL END AS Quarter_Allign,
DATE_FORMAT(@date ,'%Y-%m-01 00:00:00') AS Month_Allign,
DATE_FORMAT(@date ,'%Y-%m-%d 00:00:00') AS Day_Allign;
SET @date = '2013-05-03 10:05:00';
SET @allign = '1_QUARTER';
SELECT
CAST(@date AS DATETIME) AS Date,
CASE @allign
WHEN '1_YEAR' THEN DATE_FORMAT(@date ,'%Y-01-01 00:00:00')
WHEN '1_QUARTER' THEN (CASE EXTRACT(QUARTER FROM @date)
WHEN 1 THEN DATE_FORMAT(@date ,'%Y-01-01 00:00:00')
WHEN 2 THEN DATE_FORMAT(@date ,'%Y-04-01 00:00:00')
WHEN 3 THEN DATE_FORMAT(@date ,'%Y-07-01 00:00:00')
WHEN 4 THEN DATE_FORMAT(@date ,'%Y-10-01 00:00:00')
ELSE NULL END)
WHEN '1_MONTH' THEN DATE_FORMAT(@date ,'%Y-%m-01 00:00:00')
WHEN '1_DAY' THEN DATE_FORMAT(@date ,'%Y-%m-%d 00:00:00')
ELSE NULL
END AS Alligned;
函数应返回时间间隔,4种可能:天、月、季度、年。在程序的第一部分(我在这个问题中讨论的),它应该找到第一时间间隔。因此,例如,如果我选择季度间隔,并将开始日期时间输入为“2013-05-03”,则此代码应将我的输入更正为“2013-04-01”,因为这是第二季度的真正开始,我给定的开始日期适用于该季度。如果我选择了年间隔,我的函数应该将我的输入日期更改为给定年份的第一个一月,如果我的输入日期不是第一个一月。你不能使用更简单的方法,比如或@lad2025,这将是很好的答案。暗示hint@Schwern作为答案发布供将来参考:)谢谢你告诉我问题出在哪里。我已经习惯了postgreSQL,这是我必须在MySQL中完成的一个项目,所以这对我来说是很大的帮助。:)