在MySQL中,如何将列中的文本字符仅替换为日期值,而不是VARCHAR数据类型?

在MySQL中,如何将列中的文本字符仅替换为日期值,而不是VARCHAR数据类型?,mysql,regex,date,Mysql,Regex,Date,我有一个表,其中有一列日期,其中的各种值已从Excel日期等清理到mysql日期,我想运行的最后一步是在运行alter命令将数据类型更改为date之前删除列中的任何非日期值,但不幸的是,我编写的查询给了我一些提示问题。以下是我的日期示例: CREATE TABLE `date_checks` ( `Start_Date` varchar(255) DEFAULT NULL ); 我的发言: INSERT INTO `date_checks`

我有一个表,其中有一列日期,其中的各种值已从Excel日期等清理到mysql日期,我想运行的最后一步是在运行alter命令将数据类型更改为date之前删除列中的任何非日期值,但不幸的是,我编写的查询给了我一些提示问题。以下是我的日期示例:

CREATE TABLE `date_checks` 
        (  
        `Start_Date` varchar(255) DEFAULT NULL
        );
我的发言:

INSERT INTO `date_checks` (`Start_Date`) VALUES
('04/04/2018'),
('01/05/2018'),
('3 years'),
('28/05/2018');
我的输出

Start_Date
    04/04/2018
    01/05/2018
    3 years
    28/05/2018
我正在运行的查询如下所示:

UPDATE 'date_checks' SET Start_Date = '' WHERE Start_Date NOT REGEXP '^[0-9]';
现在我在猜测,因为我在第三行的开始处有值3,这不会被删除,所以我只是想得到一些帮助,以确保我这样做是正确的,因为我希望在本列中的所有内容都是日期值。我写的REGEXP寻找的是所有不是以数字开头的东西,但我猜我需要将其扩展到列中日期的方式,以使其更加具体和准确

如果上面的代码运行正常,那么我将运行以下命令来更改数据类型:

ALTER TABLE date_checks MODIFY Start_Date DATE;

如果有人能告诉我这是正确的,我将不胜感激。

MySQL不理解DD/MM/YYYY格式的日期。如果执行显示的ALTER TABLE语句,则无法将这些日期转换为其日期类型值

您需要将字符串转换为YYYY-MM-DD格式

我建议从一个新专栏开始:

ALTER TABLE date_checks ADD COLUMN Start_Date2 DATE;
然后将值复制到新列

UPDATE date_checks SET Start_Date2 = STR_TO_DATE(Start_Date, '%d/%m/%Y');
ALTER TABLE date_checks DROP COLUMN Start_Date, 
    CHANGE COLUMN Start_Date2 Start_Date DATE;
如果类似“3年”的字符串的格式与该函数中的格式字符串不匹配,则STR_TO_DATE()返回NULL

因此,在这次更新之后,您将把大部分日期复制到正确的格式中,但是那些无法解析的日期将为空

然后,您可以检查未能解析的异常情况。这些可能足够少,您需要在新列中手动更新它们

SELECT Start_Date FROM date_checks WHERE Start_Date2 IS NULL;
手动分配任何要保留的开始日期字符串后,剩余的开始日期字符串不值得保留。然后您可以随意删除旧列,并重命名新列

UPDATE date_checks SET Start_Date2 = STR_TO_DATE(Start_Date, '%d/%m/%Y');
ALTER TABLE date_checks DROP COLUMN Start_Date, 
    CHANGE COLUMN Start_Date2 Start_Date DATE;

请回复您的评论:

如何更改更新代码以同时接受这两种代码

我不知道是否有必要一次性完成这项工作。您可以分几步完成:

UPDATE date_checks SET Start_Date2 = STR_TO_DATE(Start_Date, '%d/%m/%Y');
UPDATE date_checks SET Start_Date2 = STR_TO_DATE(Start_Date, '%d-%m-%Y') WHERE Start_Date2 IS NULL;
UPDATE date_checks SET Start_Date2 = STR_TO_DATE(Start_Date, '%d.%m.%Y') WHERE Start_Date2 IS NULL;
...other formats...
因此,在每次传递之后,更少的行在Start_Date2中仍然为NULL。您可以根据需要继续尝试其他格式,直到没有任何空值,或者您想放弃,因为最后几个掉队的无法解析

比如,如果剩下一个,你会怎么做,但是
Start\u Date
中的字符串写着,“和我的舌头一样老,比我的牙齿稍微老一点”

如果确实需要一次完成,可以使用COALESCE()进行多次尝试:

UPDATE date_checks SET Start_Date2 = COALESCE(
  STR_TO_DATE(Start_Date, '%d/%m/%Y'),
  STR_TO_DATE(Start_Date, '%d-%m-%Y'),
  STR_TO_DATE(Start_Date, '%d.%m.%Y')
  ...other formats...
);

COALESCE()返回其第一个非NULL参数。因此,它将按从左到右的顺序尝试每个STR_TO_DATE()调用,结果将是第一个成功的调用。如果没有成功,则为空。

那么,对于不会成为MySQL日期数据类型的
3年
或这种格式的
28/05/2018
您首先是如何加载excel数据的呢。这是一次性过程还是常规过程?3年值必须变为空值,因此空值在此列中是不可接受的。我的完整数据库中的总数据为150万行,我给出的示例是我遇到的导致问题的随机示例。谢谢你,比尔,我会仔细考虑你的建议,让你知道我的进展情况。嗨,比尔,我刚刚完成了您在我的主表中提到的过程,遇到了一些日期,其除法器值为“-”,而不是“/”。我如何更改更新代码以同时接受这两种代码?我是指日期部分之间的分隔符。非常感谢Bill的详细解释,这对我很有帮助,我已经设法解决了日期问题,