CSV日期导入SQL DATE字段异常及格式适配问题咨询
嘿,这个问题我之前也碰到过,给你捋清楚关键点:
首先搞懂一个核心误区
SQL里的DATE/DATETIME/TIMESTAMP类型根本不存储显示格式——它们存的是底层的时间数值(比如从某个纪元开始的秒数),你看到的"YYYY-MM-DD"只是数据库客户端或者会话设置的默认显示格式。所以你没法直接修改DATE字段的"格式",因为它本身就没有格式这一说。
而且你的场景里用DATE类型本身就不合适:DATE只存储日期部分(年-月-日),你的CSV里带了时分秒,导入时数据库解析失败,就会返回无效的0000-00-00。如果需要保留时间信息,应该用DATETIME或者TIMESTAMP类型。
解决方案:不用改CSV,导入时指定解析规则
你完全不需要提前把CSV转成YYYY-MM-DD格式,只要在导入的时候告诉数据库怎么解析你的日期字符串就行。以MySQL为例,假设你用LOAD DATA INFILE导入,写法大概是这样:
LOAD DATA INFILE '/path/to/your/file.csv' INTO TABLE your_table FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 LINES -- 如果CSV有表头的话 (@raw_date, other_column1, other_column2) -- 先把日期暂存到变量@raw_date SET your_datetime_column = STR_TO_DATE(@raw_date, '%m/%d/%Y %h:%i:%s %p');
这里的%m/%d/%Y %h:%i:%s %p就是对应你CSV里的"3/8/2018 9:05:00 AM"格式:
%m:两位月份(如果是一位月份比如3,用%c也可以)%d:日期%Y:四位年份%h:12小时制的小时%i:分钟%s:秒%p:AM/PM标识
这样导入后,your_datetime_column(类型设为DATETIME)就会正确存储时间,排序的时候直接按字段排序就行,完全符合需求。
关于显示格式的调整
如果想让查询结果显示成mm/dd/yyyy hh:mi:ss的格式,不用改字段,只要查询时用DATE_FORMAT函数转换:
SELECT DATE_FORMAT(your_datetime_column, '%m/%d/%Y %h:%i:%s %p') AS formatted_date FROM your_table;
要是想让当前会话的所有查询默认显示这个格式,也可以临时修改会话设置:
SET session date_format = '%m/%d/%Y %h:%i:%s %p'; SET session time_format = '%h:%i:%s %p';
为啥varchar导入后丢了秒?
这个大概率是你用的导入工具(比如phpMyAdmin、Navicat之类)的自动截断设置,或者工具默认忽略了时间部分的秒。但绝对不要用varchar存日期——字符串排序的逻辑和日期完全不一样,比如"10/1/2020"会排在"3/8/2023"前面,这显然不符合你按日期排序的需求。
内容的提问来源于stack exchange,提问作者Ken

