MySQL查询报错:STR_TO_DATE别名及WHERE子句未知列问题排查
解决MySQL中STR_TO_DATE相关的两个常见问题
嘿,这两个问题其实都和MySQL的执行逻辑以及语法规则有关,我来给你拆解清楚:
问题1:将STR_TO_DATE作为列使用时提示“列不存在”
你大概率是直接把STR_TO_DATE当成表的列名来用了(比如写了SELECT STR_TO_DATE FROM dates;),但STR_TO_DATE是MySQL的内置日期转换函数,并不是你表中实际存在的列。
要正确使用它,必须按照函数语法传入参数:STR_TO_DATE(待转换的日期字符串列, 格式模板)。举个实际的例子:
假设你的dates表中有个start列,存的是dd/mm/yyyy格式的字符串日期,要把它转换成标准日期格式,正确写法是:
SELECT STR_TO_DATE(start, '%d/%m/%Y') AS formatted_date FROM dates;
这里的AS formatted_date是给转换后的结果起一个别名,方便后续识别——不过别着急在WHERE子句里直接用这个别名,这正是第二个问题的坑点。
问题2:WHERE子句使用别名date_format触发“列不存在”错误
这是MySQL执行顺序导致的经典坑!MySQL处理查询的顺序是:
- 先执行
FROM确定要查询的表 - 接着执行
WHERE子句过滤行 - 最后才会执行
SELECT子句生成列(包括给列起别名)
所以当你在WHERE里写date_format >= 2018-03-19时,MySQL还没执行到SELECT步骤,根本不知道date_format这个别名对应的是什么,自然会报“未知列”的错误。另外还要注意:你写的2018-03-19没有加单引号,MySQL会把它当成数值计算(2018-3-19=1996),这完全不是你想要的日期对比!
给你两种解决方法:
方法一:在WHERE子句中重复使用STR_TO_DATE函数
直接在过滤条件里写完整的函数调用,同时记得给日期值加单引号:
SELECT *, STR_TO_DATE(start, '%d/%m/%Y') AS date_format FROM dates WHERE STR_TO_DATE(start, '%d/%m/%Y') >= '2018-03-19';
方法二:用子查询/CTE先生成别名列再过滤
如果函数逻辑比较复杂,不想重复写,可以先用子查询或者CTE(MySQL 8.0及以上版本支持)先生成带别名的临时结果集,再在外层过滤:
子查询写法:
SELECT * FROM ( SELECT *, STR_TO_DATE(start, '%d/%m/%Y') AS date_format FROM dates ) AS temp_table WHERE date_format >= '2018-03-19';
CTE写法(更易读):
WITH temp_dates AS ( SELECT *, STR_TO_DATE(start, '%d/%m/%Y') AS date_format FROM dates ) SELECT * FROM temp_dates WHERE date_format >= '2018-03-19';
内容的提问来源于stack exchange,提问作者natas
相关产品推荐
相关产品推荐

