前語:使用的sql多了不知道大家有沒這樣的困惑,sql的語法大的方面是一致的,如select,join,group by等,但是在一些函式或某些特定功能處理上還是有很大差異的,而這些差異經常給大家帶來困惑,尤其是乙個新手從一種sql轉到另一種sql的時候,總是抓耳撓腮,不知所措。今天就把大家常用的sql語言做乙個總結,來看看他們在日期時間處理方面的差異。
前置說明:本文所用的日期時間均指:2020-07-20 10:58:59這種格式,時間戳指:1595932031這種格式。
一、日期處理函式
hive:select create_time,from_unixtime(create_time,'yyyy-mm-dd hh:mm:ss') from table1; --這是標準的寫法,如果不加'yyyy-mm-dd hh:mm:ss'同樣可以返回到秒的結果,如果只需要格式化到小時、分鐘等的話只給出到對應位置的格式化引數即可。
presto: select create_time,from_unixtime(create_time),format_datetime(from_unixtime(create_time),'yyyy-mm-dd hh:mm:ss') from tables1;--from_unixtime不需要使用格式化引數來指定格式化的位數而且create_time的型別必須是數值型,如果不是需要先使用cast轉為數值型才可,或者會報錯,預設返回到毫秒經度。如果需要指定返回的精度配合format_datetime使用即可。
spark:select create_time,from_unixtime(create_time,'yyyy-mm-dd hh:mm:ss') from table1; --由於spark底層使用的hive的執行解析計畫,所以這裡與hive的使用基本一致。
impala:select create_time,from_unixtime(cast(create_time as bigint)+28800,'yyyy-mm-dd hh:mm:ss') from table1; --兩個需要注意的地方,create_time不支援string型別,只能是數值型;這裡加上28800(8個小時)主要是解決impala時區的問題,因為impala預設的不是中國時區,需要加上28800才能與正常的中國時區保持一致。
mysql:select create_time,from_unixtime(create_time,'%y-%m-%d %h:%i:%s) from table1;--這裡需要注意的地方create_time必須是數值型別的;如果不加格式化引數的話預設是返回到秒的,需要使用格式引數的話加上對應的格式化引數即可。
以上的執行結果為:假設create_time為'1522128932',轉換後的結果為:'2018-03-27 13:35:32'
hive:select unix_timestamp(create_time,'yyyy-mm-dd hh:mm:ss') from table1;--需要注意的地方:如果create_time是標準的到秒級的時間可以不指定格式化引數,如果不是標準的到秒級的日期必須根據create_time到哪一位後面對應到格式化話哪一位,否則會返回空值或者是不正確的結果。
presto:select cast(to_unixtime( cast ( create_time as timestamp)) as bigint) from table1;--需要注意的地方,首先presto這裡的轉換使用起來比較麻煩,需要to_unixtime和timestamp結合起來使用才行。這裡的create_time不用指定格式化的引數,會根據具體的值來解析。
spark:select unix_timestamp(create_time,'yyyy-mm-dd hh:mm:ss') from table1;--與hive的使用保持一致。
impala:select unix_timestamp(create_time,'yyyy-mm-dd hh:mm:ss')+28800 from table1;--需要注意的地方轉換後需要加上28800才能與中國時區保持一致,create_time如果是標準的日期時間格式的話可以不指定格式化引數,否則必須要指定格式化引數。
mysql:select unix_timestamp(created_time) from table1;--這裡不需要指定格式化引數,否則會報錯,需要注意
以上執行結果:假設create_time為'2018-03-27 13:35:32',轉換後的結果為:'1522128932'
hive:selecct datediff(date1,date2) from table1;--計算兩個日期之間的天數差值,是拿date1的日期「減去」date2的日期,即使date1和date2精確到的粒度不一致,如date1到天,date2到分鐘結果仍然只是天粒度的差值。
presto:select date_diff('day',cast(date1 as date),cast(date2 as date)) from table1;--這裡需要三個引數,第乙個引數指定計算的是「天」差值、「小時」差值等,另外需要把date1和date2轉為date型別,否則sql會報錯。
spark:selecct datediff(date1,date2) from table1;--使用hive保持一致
impala:select datediff(date1,date2) from table1;--這裡的使用基本上與hive保持一致
mysql:selecct datediff(date1,date2) from table1;--基本與hive的用法一致
說明:有了以上兩步日期和時間戳之間的互轉,這裡求兩個日期的時間差值就相對來說比較簡單了,如果不是標準的日期時間格式先轉為日期時間格式即可。
hive:select date_add/date_sub(date1,n) from table1;--date_add和date_sub分別是向後推n天和向前推n天,另外這裡增加或減少後日期只精確到天,即使date1是精確到秒粒度的計算結果最終仍然是到天粒度。
presto:select date_add('day', n, cast(date1 as date) ) from table1;--這裡同樣需要三個引數後推日期的粒度,後推多少天,基準日期。另外需要注意preto這裡沒有date_sub函式,需要使用的話可以把第二個引數改為負值即可。
spark:select date_add/date_sub(date1,n) from table1;--使用上與hive保持一致。
impala:select adddate/days_add(date1,n) from table1;--在這個功能實現上adddate和days_add均可使用,需要注意date1要麼精確到天(2020-07-01)要麼精確到秒(2020-07-01 12:12:11)其他格式會返回空值。另外即使date1只精確到返回結果仍然是到秒的。
mysql:select date_add/date_sub(date1,interval n day) from table;--需要指定後推/前移的天數,如果date1只精確到天則結果也是精確到天,如果date1精確粒度到天後面的級別則會返回秒級別的粒度。
說明:好多sql中支援date_add/date_sub,其實使用乙個即可,把相對應的n值取為負值即可。
hive:select substr(current_timestamp(),1,19)/from_unixtime(unix_timestamp(),"yyyy-mm-dd hh:mm:ss") from table1;--兩種方式均可,建議使用第一種更為簡潔,返回的是標準的秒級粒度的日期時間。
presto:select current_date/current_time from table1;--current_date返回的是天級粒度的日期時間(2020-01-02)這種,current_time 返回的是當前時間對應的小時、分鐘和秒(12:12:11)這種。
spark:select substr(current_timestamp(),1,19)/from_unixtime(unix_timestamp(),"yyyy-mm-dd hh:mm:ss") from table1;--使用上和hive保持一致
impala:select mow() /current_timestamp() from table1;--比較簡單,兩個函式返回的結果相同,但是注意返回的是到毫秒的日期時間格式,如果需要到天粒度的話可以擷取處理。
mysql:select sysdate()/now() from table1;--兩個函式返回的結果一致,都是到秒粒度的日期時間。
以hive為基準,從以上例子可以看出spark的語法基本完全兼hive;presto與其他幾個相比使用起來稍顯麻煩主要是由於其支援多種資料來源,其上要做統一的封裝;impala時區的問題需要注意,否則會帶來資料上的困擾和不一致性。 sql中日期時間相關函式
增加日期 date add adddate select date add 2020 11 04 interval 31day date 輸出 2020 12 05 select adddate 2020 11 04 31 date 輸出 2020 12 05計算兩個時間差 timestampdif...
一文搞定聯合索引
聯合索引 上文講解了索引的底層結構,但是留了乙個尾巴,就是沒有去講復合索引。今天來繼續梳理復合索引,所謂復合索引即是由多個字段組成的一條索引。例如下表 create table test id int 4 notnull auto increment a varchar 10 not null b ...
一文搞定babel轉換
code轉換為ast 遍歷ast樹 進行修改 還原為code targets支援哪些瀏覽器 babel polyfill是將整個es2015 環境引入到全域性中,會造成全域性汙染require core js modules set 改變了原型,所以可以在例項上使用方法 通過配置usebuiltin...