tableau踩坑记录1:处理MySql 的bug——时间列被自动加上一个月
在本地编辑前跑出来是1月1日的订单,有极少部分变成了2月1日!实际上付费时间是1月1日,却被硬生生地加上了一个月。而且还是局部bug,并不是所有订单都是,有点无厘头。MySQL取数的时候,如果时、分、秒都是0,可能会强制加一个月,可以用date()等时间函数做转换,以规避问题。...............
一、问题来源
今天接到一个需求,需要给订单数据需要新增一些分类。仅仅是对原来的订单修改类别即可,但是,改完SQL代码,提取数据之后,发现面板的历史订单数据竟然发生了变化!
经过一番排查,定位到了问题——在本地编辑前跑出来是1月1日的订单,有极少部分变成了2月1日!实际上付费时间是1月1日,却被硬生生地加上了一个月。而且还是局部bug,并不是所有订单都是,有点无厘头。
二、疑问与解惑
- 为什么会发生这样的事情,是什么原因导致这极少的部分发生了bug?
- 之前不会的,为什么这次不行了?
- 为什么是这极少部分,而不是其他?
针对以上的问题,提出几个假设,接下来逐一解决。
由于急于交付,先不考虑产品层面的优化,先找数据规律,以处理数据问题,交付需求。后续再探索产品层面的优化。
2.1 假设1:这极少部分数据存在某些的规律,导致tableau误判。
将目前定位到出问题的订单都拉出来,看看是否有什么规律。看了许久,看不出有什么特别的。百度谷歌也变换各种关键词,找了好一段时间,无果。心态有点崩。
后来一个偶然的机会,脑子里蹦出了一个词:数据类型。
于是尝试修改了数据类型跑数据看看,终于能正常显示日期了!
效果如下图,使用了脱敏数据进行演示。
推广到全部数据,跑完终于能和原来的数据对上!
后来和同事交流中发现,他也有这样的问题,当时他总结出来的经验就是: > MySQL取数的时候,如果时、分、秒都是0会强制加一个月,需要用date()函数强制转化为日 。
基于此,我又有一个新想法,既然时分秒都是0会加一月,那就给秒加上1秒或者修改为1秒,这样是不是就可以了呢?验证结果是可以的,大多数情境下,数据的精确度顶多到分钟级别,都不会到秒级别,秒的单位是可以忽略不计的。
下面做一个汇总,按需取:
-- 转化为日期
date(col_time);
-- 时间加1秒
date_add(col_time,interval 1 second);
-- 将秒改为01,注意:该函数是转换成了字符串
date_format(col_time,"%Y-%m-%d %H:%i:01");
执行结果如下图:
- 通过该方法解决,最好是通过
date()
转化为日期,这样子不会对原来的日期有所影响,也不用再转化为字符串再转回时间;不足之处就是看不小详细的时间,在不需要具体时间时可优先考虑; - 通过
date_add()
加1秒,基本上也不会有多大的影响,但是不排除有一些比较极端的情况,偏偏是在59分59秒,甚至是23:59:59
加上1秒变成了第二天的数据,需要谨慎处理; - 通过
date_format()
进行转化,将秒数统一转化为01
这个对年月日时分都没有影响,也是一个比较理想的处理方式,但是处理完变成了字符串,如果要当成时间使用,需要再转换数据类型,当数据量太大时,性能会很差,当然十万百万的应该问题不大。
虽然问题能够通过函数解决了,但是这并不能从根本上解决问题。每次都要对这种数据进行类型转换,偶尔可能会一不小心再次踩坑。需要寻找一个更好的解决方案。
2.2 假设2:再探索,是Tableau版本的问题所导致。
去官网查了相关版本的迭代说明,都没有说到该bug的优化,看来真的是有点隐蔽。
不过还是抱着试试的心态,重新下载安装对应大版本下的最新版。由于公司采购的是2021.2版本的Tableau sever,为了保证兼容性,选择了最新的(Tableau Desktop 2021.2.14),结果一样,应该不是版本问题。
Tableau Desktop历史版本官方下载链接:https://www.tableau.com/support/releases
2.3 假设3:是ODBC连接器的问题所导致。
卸载已安装的ODBC驱动,然后到MySQL官方网站重新下载一个ODBC驱动并安装,但是效果并不理想。还是没能从根本上解决问题。
Tableau Desktop驱动下载链接:https://www.tableau.com/zh-cn/support/drivers(或直接到MySQL的ODBC连接器官网下载:https://dev.mysql.com/downloads/connector/odbc/)
Tableau官方连接数据库教程:https://help.tableau.com/current/pro/desktop/zh-cn/examples_mysql.htm
2.4 其他补充
做了那么多但是都没能从根本上解决问题,后来要写这篇文章的时候,下载了MySQL,并在本地创建了表单,进行关联,结果竟然让我感到很惊讶!
跑出来的结果并没有问题!如下图:
再试试其他地址的数据库,也没有该问题……
再看看Tableau Server 上的面板,也有类似的字段,也没有问题……
再通过自己电脑试试同一段SQL(包括自己本地和公司的数据库)也没有问题……
好吧,该问题真的太无厘头了,确实也不普遍!一个不合适的时机,一对不合适的产品,促成了一个不合适的结果。
三、总结
MySQL取数的时候,如果时、分、秒都是0,可能会强制加一个月,可以用date()
、date_add()
、date_format()
等时间函数做转换,以规避问题。
语法参考:
-- 转化为日期
date(col_time);
-- 时间加1秒
date_add(col_time,interval 1 second);
-- 将秒改为01,注意:该函数是转换成了字符串
date_format(col_time,"%Y-%m-%d %H:%i:01");
暂时没有找到从根本上解决该问题,就先这样吧,后续看看有没有一个合适的时机,打破这个不合适的结果,再来更新。
2022-07-07更(已解决)
终于,在一个偶然合适的时机把问题给解决了!问题的根源就是ODBC插件的问题,ODBC插件和MySQL版本不匹配。
主要原因就是公司数据库是MySQL 5.6,而我的驱动是MySQL 8.0的,二者不兼容所致。
为什么会突然出现这样的问题呢?因为我前6月28日下载了一个新版的MySQL,附带ODBC插件,自动帮我的电脑重装了,之前装的是MySQL 5.6 的。
前面验证的时候为什么没有找到根源呢?因为在MySQL 8.0徘徊是没有结果的……
如果本文对您有帮助,记得点赞👍收藏⭐哦!
如果想了解我更多相关领域的好文,记得👀关注
我哦,之后每一次更新都会在首页
-关注
下第一时间收到通知,不错过每一篇好文!
更多推荐
所有评论(0)