我有一个表,其中分别包含'year'
,'month'
,'day'
,'hour'
和'minute'
列。
除'month' (VARCHAR)
外的所有INTEGER列,我添加了一个新列以将所有内容放在一起'date_time' (TIMESTAMP)
。
+------+-------+------+------+--------+-----------+
| year | month | day | hour | minute | date_time |
+------+-------+------+------+--------+-----------+
| 1987 | 12 | 15 | 9 | 25 | <NULL> |
| 1997 | 10 | 10 | 10 | 40 | <NULL> |
| 1994 | 08 | 9 | 6 | 30 | <NULL> |
+------+-------+------+------+--------+-----------+
我这样查询以填充'date_time'
列:
UPDATE dates
SET date_time =
COALESCE(
STR_TO_DATE(
CASE WHEN
CONCAT(
year,
'-',
CASE WHEN LPAD(month, 2, 0) BETWEEN 1 AND 12 THEN LPAD(month, 2, 0) ELSE NULL END,
'-',
CASE WHEN LPAD(day, 2, 0) BETWEEN 1 AND 31 THEN LPAD(day, 2, 0) ELSE NULL END,
' ',
CASE WHEN LPAD(hour, 2, 0) BETWEEN 0 AND 23 THEN LPAD(hour, 2, 0) ELSE NULL END,
':',
CASE WHEN LPAD(minute, 2, 0) BETWEEN 0 AND 59 THEN LPAD(minute, 2, 0) ELSE NULL END,
':00'
)
LIKE '%NULL%' THEN NULL
ELSE
CONCAT(
year,
'-',
CASE WHEN LPAD(month, 2, 0) BETWEEN 1 AND 12 THEN LPAD(month, 2, 0) ELSE NULL END,
'-',
CASE WHEN LPAD(day, 2, 0) BETWEEN 1 AND 31 THEN LPAD(day, 2, 0) ELSE NULL END,
' ',
CASE WHEN LPAD(hour, 2, 0) BETWEEN 0 AND 23 THEN LPAD(hour, 2, 0) ELSE NULL END,
':',
CASE WHEN LPAD(minute, 2, 0) BETWEEN 0 AND 59 THEN LPAD(minute, 2, 0) ELSE NULL END,
':00'
)
END,
'%Y-%m-%d %H:%i:%s'
),
'0000-00-00 00:00:00'
);
有效,但是... 我的问题是,是否有一种更简单的方法来编写查询以执行相同的操作。
答案 0 :(得分:1)
在DATE()
函数中以“ YYYYMMDD”格式输入数字或字符串将得出DATE。
MAKETIME()
函数接受小时,分钟和秒返回TIME。
然后,当您在DATE和TIME之间用空格隔开时,可以将结果字符串放在DATETIME或TIMESTAMP中。
UPDATE dates
SET date_time = CONCAT(DATE(year*10000 + month*100 + day),' ',MAKETIME(hour,minute,0));
对 db <>小提琴here
的测试答案 1 :(得分:0)
您可以使用STR_TO_DATE
将字符串转换为datetime
。第二个参数是格式说明符,可用于描述输入数据的格式。对于某些用例,可以使用格式说明符,例如:
%c
:以数字表示的月份,例如1、2、3…12 %e
:一个月中的日期,不包含前导零,例如1,2,…31 %k
:24小时制的小时,不加零,例如0,1,2…23 我看不到“没有前导零的分钟数”和“没有前导零的秒数”的格式说明符,但是似乎没有引起MySQL处理它们的问题(我在MySQL 8.0上进行了测试)。
所以我想你可以做到:
UPDATE dates
SET datetime = STR_TO_DATE(
CONCAT(year, '-', month, '-', day, ' ', hour, ':', minute, ':', second),
'%Y-%c-%e %k:%i:%s'
)