Clickhouse 时区转换(下)
Clickhouse 时区转换续—时区参数转换
天天加班,时间不够,主要还是我太懒,流汗,,,,,,另外如果这篇学习笔记超过100阅读量并有评论,我可能半夜也会爬起来更新的。
相信大家看我之前记录的这篇文章,参考链接:https://www.cnblogs.com/thxj/p/12642041.html,
对Clickhouse 时区转换有了一定的了解,但是如果要完全应用到工作业务中去,你可能还是会遇到问题。
👇回顾:
select toTimeZone(toDateTime('2020-04-06 02:00:00'), 'Asia/Hong_Kong') , toString(toDateTime('2020-04-06 02:00:00'), 'Asia/Hong_Kong')
这个是我们之前的案例,执行语句都可以正确转换你想要的时区,但是如果你要把 '2020-04-06 02:00:00' 这个转换为参数 created_at,或者把 'Asia/Hong_Kong' 转换为参数 time_zone,
那用toTimeZone(),toString() 时区转换就会失效报错。
我们想要看看mysql 的实现效果: created_at 是datetime 类型,默认时区是UTC 也就是0 时区,我们需要从UTC (0时区) 转换为 New_York (西五区),数据成功转换。
我们来看看Clickhouse
/*默认时区UTC,created_at 是DateTime类型,执行都会报错,clickhouse 还不支持时区参数传递,只能写一个时区A,把UTC 时区的数据全部转换为时区A ;如果每一条记录都有对应的时区,比如id =1 的时区是 北京时区,id = 2 的时区 是纽约时区,这样的需求就不能满足*/ select toTimeZone(created_at,time_zone); select toString(created_at,time_zone); select toString(created_at + time_zon);
时区,特别是跨过业务的公司很常用到。
👇方案:
就是把time_zone 转换为秒,在clickhouse 添加一个time_zone_second, INT 类型 ,比如,香港是东八区,转换为秒: 8* 60*60 = 28800;纽约是西五区,转换为秒:-5 * 60*60 = -14400
created_at time_zone time_zone_second
2017-08-09 10:15:0 Asia/Hong_Kong 28800
2011-03-17 20:35:38 America/New_York -14400
方案一:用 toString(created_at + time_zone_second) 实现时区的转换
执行下面👇语句,时区默认是当前系统时区:
select time_zone time_zone_second , created_at, toString(created_at + time_zone_second ) as string_change, /*时区转换成功,数据类型是 String */ toDateTime(toString(created_at +time_zone_second )) as datetime_change,/*时区转换成功,数据类型是 DateTime*/ toTypeName(toDateTime(toString(created_at +time_zone_second ))) as TypeName from time_zone_test ;
执行结果👇:
执行结果 please note that:这个是根据时间相加减变相地实现时区进行时区转换,正确的显示来我们想要的结果。我们看到结果后面的TypeName 是Datetime ,但是没有带显示这个时间的所属的时区, 在上一篇文章的toTimeZone函数,通过该函数,我们是可以知道转换时区后的所属的时区的。不信你看👇:
select toTypeName(toTimeZone(toDateTime('2020-04-06 02:00:00', 'UTC'), 'Asia/Hong_Kong')) as TypeName;
方案二:addSeconds()
select created_at as CreatedAt, addSeconds(created_at,time_zone_second) as DateTime, toTypeName(addSeconds(created_at,time_zone_second)) as TypeName from time_zone_test;
执行结果👇:
时区转换结果正确,我们也看到这个转换后的所属时区还是显示数据库的默认时区。
两种方案都可以使用,个人觉得第二种方案跟容易理解和实操,大家也可以用 addHours() ,addMinutes() ,addSeconds() 根据方案二的方式进行转换哦 。