Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 使用str_to_DATE将子字符串转换为日期_Mysql_Database - Fatal编程技术网

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”是一个问题