Mysql 使用str_to_DATE将子字符串转换为日期
我有一个很简单的问题。然而,我已经进行了广泛的研究,还没有找到解决方案。基本上,我想将修改后的字符串变量转换为日期格式(特别是Mysql 使用str_to_DATE将子字符串转换为日期,mysql,database,Mysql,Database,我有一个很简单的问题。然而,我已经进行了广泛的研究,还没有找到解决方案。基本上,我想将修改后的字符串变量转换为日期格式(特别是%Y) 我有一个名为dob的列变量,其中包含VARCHAR格式的日期。这些字符串的值各不相同,可以类似于以下任意值:01 JAN 1900、ABT 1960、或Unknown。尽管如此,年份始终是最后四位数字,因此我通过创建子字符串来获取年份。但我想将该子字符串转换为YEAR格式。我的想法是,我需要使用str\u to\u date来实现这一点 这是我的MySQL查询:
%Y
)
我有一个名为dob
的列变量,其中包含VARCHAR
格式的日期。这些字符串的值各不相同,可以类似于以下任意值:01 JAN 1900
、ABT 1960
、或Unknown
。尽管如此,年份始终是最后四位数字,因此我通过创建子字符串来获取年份。但我想将该子字符串转换为YEAR
格式。我的想法是,我需要使用str\u to\u date
来实现这一点
这是我的MySQL查询:
SELECT dob, STR_TO_DATE(SUBSTRING(dob, -4), "%Y") as YEAR
FROM person_table;
运行它时,我只得到NULL
值。有什么我遗漏的吗
以下是我的MySQL规范:
innodb_version: 5.7.20
protocol_version: 10
谢谢你的帮助
编辑:提供SQL模式信息:
+---------------+-----------------------------------------------------------+
| Variable_name | Value |
+ --------------+-----------------------------------------------------------+
| sql_mode | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+------------------------------------------------------------
1 row in set (0.00 sec)
运行查询时,选择STR_TO_DATE('2009','%Y')代码>我得到NULL
和以下警告:
I get the following warning:
+---------+------+-----------------------------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------------------------+
| Warning | 1411 | Incorrect datetime value: '2009' for function str_to_date |
+---------+------+-----------------------------------------------------------+
1 row in set (0.00 sec)
str_to_date
返回一个date
类型,并且只有一年是不完整的日期str_to_date
将用零填充未完成的部分,除非您启用了模式。这是MySQL 8.0中默认设置的一部分;它避免了MySQL最糟糕的怪癖
严格模式控制MySQL如何处理数据更改语句(如INSERT或UPDATE)中的无效或缺失值。值可能因多种原因而无效。例如,该列的数据类型可能错误,或者可能超出范围
如果没有严格的SQL模式,MySQL将把“2009”变成无效日期2009-00-00
mysql> set sql_mode = '';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT STR_TO_DATE('2009','%Y');
+--------------------------+
| STR_TO_DATE('2009','%Y') |
+--------------------------+
| 2009-00-00 |
+--------------------------+
1 row in set (0.00 sec)
在严格的SQL模式下,它不会
mysql> show variables like 'sql_mode';
+---------------+-----------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value |
+---------------+-----------------------------------------------------------------------------------------------------------------------+
| sql_mode | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION |
+---------------+-----------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT STR_TO_DATE('2009','%Y');
+--------------------------+
| STR_TO_DATE('2009','%Y') |
+--------------------------+
| NULL |
+--------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> show warnings;
+---------+------+-----------------------------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------------------------+
| Warning | 1411 | Incorrect datetime value: '2009' for function str_to_date |
+---------+------+-----------------------------------------------------------+
1 row in set (0.00 sec)
为了解决您的问题,我建议您尝试几种格式,从最具体的使用到最不具体的使用,而不是尝试进行一刀切的转换。您必须根据需要添加缺少的日期部分
select coalesce(
str_to_date(dob, '%d %b %Y'),
str_to_date(concat(dob, '-01-01'), 'ABT %Y-%m-%d')
)
from person_table;
由于这样做非常难看,我还建议添加一个适当的date
列,并执行update
以将凌乱的字符串日期转换为适当的date
s。然后继续查询新列
alter table person_table add column dob_date date;
update person_table
set dob_date = coalesce(
str_to_date(dob, '%d %b %Y'),
str_to_date(concat(dob, '-01-01'), 'ABT %Y-%m-%d')
)
where dob_date is null;
然后,您可以检查是否有日期为空的人,检查他们的日期字段,并调整转换。根据需要迭代
select coalesce(
str_to_date(dob, '%d %b %Y'),
str_to_date(concat(dob, '-01-01'), 'ABT %Y-%m-%d')
)
from person_table;
更新
另外,是的,我需要的是2020年,而不是字符串。原因是我需要比较年份值
作为字符串,它们不会根据需要进行比较。字符串逐个字符进行比较<代码>'200'
大于字符串'1999'
mysql> select '1999' < '2000';
+-----------------+
| '1999' < '2000' |
+-----------------+
| 1 |
+-----------------+
1 row in set (0.00 sec)
mysql> select '1999' < '200';
+----------------+
| '1999' < '200' |
+----------------+
| 1 |
+----------------+
1 row in set (0.00 sec)
str_to_date
返回一个date
类型,并且只有一年是不完整的日期str_to_date
将用零填充未完成的部分,除非您启用了模式。这是MySQL 8.0中默认设置的一部分;它避免了MySQL最糟糕的怪癖
严格模式控制MySQL如何处理数据更改语句(如INSERT或UPDATE)中的无效或缺失值。值可能因多种原因而无效。例如,该列的数据类型可能错误,或者可能超出范围
如果没有严格的SQL模式,MySQL将把“2009”变成无效日期2009-00-00
mysql> set sql_mode = '';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT STR_TO_DATE('2009','%Y');
+--------------------------+
| STR_TO_DATE('2009','%Y') |
+--------------------------+
| 2009-00-00 |
+--------------------------+
1 row in set (0.00 sec)
在严格的SQL模式下,它不会
mysql> show variables like 'sql_mode';
+---------------+-----------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value |
+---------------+-----------------------------------------------------------------------------------------------------------------------+
| sql_mode | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION |
+---------------+-----------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT STR_TO_DATE('2009','%Y');
+--------------------------+
| STR_TO_DATE('2009','%Y') |
+--------------------------+
| NULL |
+--------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> show warnings;
+---------+------+-----------------------------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------------------------+
| Warning | 1411 | Incorrect datetime value: '2009' for function str_to_date |
+---------+------+-----------------------------------------------------------+
1 row in set (0.00 sec)
为了解决您的问题,我建议您尝试几种格式,从最具体的使用到最不具体的使用,而不是尝试进行一刀切的转换。您必须根据需要添加缺少的日期部分
select coalesce(
str_to_date(dob, '%d %b %Y'),
str_to_date(concat(dob, '-01-01'), 'ABT %Y-%m-%d')
)
from person_table;
由于这样做非常难看,我还建议添加一个适当的date
列,并执行update
以将凌乱的字符串日期转换为适当的date
s。然后继续查询新列
alter table person_table add column dob_date date;
update person_table
set dob_date = coalesce(
str_to_date(dob, '%d %b %Y'),
str_to_date(concat(dob, '-01-01'), 'ABT %Y-%m-%d')
)
where dob_date is null;
然后,您可以检查是否有日期为空的人,检查他们的日期字段,并调整转换。根据需要迭代
select coalesce(
str_to_date(dob, '%d %b %Y'),
str_to_date(concat(dob, '-01-01'), 'ABT %Y-%m-%d')
)
from person_table;
更新 另外,是的,我需要的是2020年,而不是字符串。原因是我需要比较年份值 作为字符串,它们不会根据需要进行比较。字符串逐个字符进行比较<代码>'200'大于字符串
'1999'
mysql> select '1999' < '2000';
+-----------------+
| '1999' < '2000' |
+-----------------+
| 1 |
+-----------------+
1 row in set (0.00 sec)
mysql> select '1999' < '200';
+----------------+
| '1999' < '200' |
+----------------+
| 1 |
+----------------+
1 row in set (0.00 sec)
什么是“年日期格式”?那会是什么“日期”呢?我应该澄清一下。我的意思是,子字符串需要转换为
YEAR
格式。我将编辑我的帖子,使之清晰。我的思考过程是,我需要使用str\u to\u date
函数来完成这一点。SUBSTRING(dob,-4)
解决不了问题的哪一部分?请向我们显示显示诸如“sql\u mode”之类的变量。
什么是“年日期格式”?那会是什么“日期”呢?我应该澄清一下。我的意思是,子字符串需要转换为YEAR
格式。我将编辑我的帖子,使之清晰。我的思考过程是,我需要使用str\u to\u date
函数来完成这一点。SUBSTRING(dob,-4)
解决不了问题的哪一部分?请向我们显示显示“sql\u mode”之类的变量。
虽然它可以解释空值,我认为这并不能解决OP的感知问题。@草莓怎么会这样?在你之前的评论中,我对你的问题感到困惑。@草莓怎么不能解决感知问题?您认为什么是感知问题?OP似乎认为“2020”与2020有所不同。虽然它可以解释空值,但我认为这并不能解决OP的感知问题。@草莓怎么会这样?在您之前的评论中,我对您的问题感到困惑。@草莓这怎么不能解决感知问题?您认为存在什么问题?OP似乎认为“2020”是一个问题