UPDATE sq_question_content as c
INNER JOIN sq_question as s ON c.question_id = s.id
SET
c.create_at = FROM_UNIXTIME(s.pubdate) ,
c.update_at = FROM_UNIXTIME(s.pubdate);
这个错误的核心原因是:sq_question.pubdate 并非 MySQL 原生的 TIMESTAMP 类型,而是以整数(Unix 时间戳,秒数)形式存储的数值(如 1459849198 是 2016年4月5日的 Unix 时间戳),直接用 CAST(...) AS DATETIME 无法将数字转为合法的 datetime 格式,因此触发 1292 错误。
解决方案:使用 FROM_UNIXTIME() 函数转换 Unix 时间戳
MySQL 提供了 FROM_UNIXTIME(unix_timestamp) 函数,可将秒级 Unix 时间戳直接转换为 DATETIME 类型,替换原来的 CAST 即可解决问题:
UPDATE `sq_question_content` AS c
INNER JOIN sq_question AS s ON c.question_id = s.id
SET
c.create_at = FROM_UNIXTIME(s.pubdate),
c.update_at = FROM_UNIXTIME(s.pubdate);
额外说明与验证步骤
1. 先验证时间戳转换结果(避免误操作)
执行更新前,先通过 SELECT 确认转换后的时间是否正确:
SELECT
s.id,
s.pubdate AS unix_timestamp, -- 原始Unix时间戳
FROM_UNIXTIME(s.pubdate) AS converted_datetime -- 转换后的datetime
FROM sq_question AS s
LIMIT 10; -- 查看前10条数据的转换结果
2. 处理毫秒级 Unix 时间戳(若存在)
如果 pubdate 是13位的毫秒级时间戳(如 1459849198123),直接用 FROM_UNIXTIME() 会得到错误时间,需先除以1000:
UPDATE `sq_question_content` AS c
INNER JOIN sq_question AS s ON c.question_id = s.id
SET
c.create_at = FROM_UNIXTIME(s.pubdate / 1000),
c.update_at = FROM_UNIXTIME(s.pubdate / 1000);
3. 过滤无效时间戳(可选)
若存在非法的时间戳值(如0、负数、超出datetime范围的数值),可通过 WHERE 条件过滤,避免再次报错:
UPDATE `sq_question_content` AS c
INNER JOIN sq_question AS s ON c.question_id = s.id
SET
c.create_at = FROM_UNIXTIME(s.pubdate),
c.update_at = FROM_UNIXTIME(s.pubdate)
WHERE
s.pubdate > 0 -- 排除0或负数
AND s.pubdate < FROM_UNIXTIME('2038-01-19 03:14:07') -- 排除超出Unix时间戳上限的值
AND FROM_UNIXTIME(s.pubdate) IS NOT NULL; -- 确保转换结果有效
4. 确认目标字段类型
确保 sq_question_content.create_at 和 update_at 是 DATETIME/DATETIME(6) 类型,若为其他类型(如 VARCHAR),需先修改字段类型:
ALTER TABLE sq_question_content
MODIFY COLUMN create_at DATETIME NOT NULL,
MODIFY COLUMN update_at DATETIME NOT NULL;