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() 根據方案二的方式進行轉換哦 。