前言
Hive是數倉建設使用頻率最高的一項技術,基于各種業務需求,使用功能函數會為我們的開發提高了很多效率。本篇是基于筆者在日常開發中使用頻率較高的函數做一次總結(同時也會給出一些業務場景幫助讀者理解),同時也是面試中經常會被問到的函數。如有遺漏,歡迎各位讀者一起交流溝通并補充進來~;
另關注公眾號"初學大數據"
后臺回復“大數據”可獲取更多關于大數據資料
數據準備
數據集
user1,https://blog.csdn.net/qq_28680977/article/details/108161655?k1=v1&k2=v2#Ref1,10,2020-09-12 02:20:02,2020-09-12
user1,https://blog.csdn.net/qq_28680977/article/details/108298276?k1=v1&k2=v2#Ref1,2,2020-09-11 11:20:12,2020-09-11
user1,https://blog.csdn.net/qq_28680977/article/details/108295053?k1=v1&k2=v2#Ref1,4,2020-09-10 08:19:22,2020-09-10
user1,https://blog.csdn.net/qq_28680977/article/details/108460523?k1=v1&k2=v2#Ref1,5,2020-08-12 19:20:22,2020-08-12
user2,https://blog.csdn.net/qq_28680977/article/details/108161655?k1=v1&k2=v2#Ref1,29,2020-04-04 12:23:22,2020-04-04
user2,https://blog.csdn.net/qq_28680977/article/details/108161655?k1=v1&k2=v2#Ref1,30,2020-05-15 12:34:23,2020-05-15
user2,https://blog.csdn.net/qq_28680977/article/details/108161655?k1=v1&k2=v2#Ref1,30,2020-05-15 13:34:23,2020-05-15
user2,https://blog.csdn.net/qq_28680977/article/details/108161655?k1=v1&k2=v2#Ref1,19,2020-05-16 19:03:32,2020-05-16
user2,https://blog.csdn.net/qq_28680977/article/details/108161655?k1=v1&k2=v2#Ref1,10,2020-05-17 06:20:22,2020-05-17
user3,https://blog.csdn.net/qq_28680977/article/details/108161655?k1=v1&k2=v2#Ref1,43,2020-04-12 08:02:22,2020-04-12
user3,https://blog.csdn.net/qq_28680977/article/details/108161655?k1=v1&k2=v2#Ref1,5,2020-08-02 08:10:22,2020-08-02
user3,https://blog.csdn.net/qq_28680977/article/details/108161655?k1=v1&k2=v2#Ref1,6,2020-08-02 10:10:22,2020-08-02
user3,https://blog.csdn.net/qq_28680977/article/details/108161655?k1=v1&k2=v2#Ref1,50,2020-08-12 12:23:22,2020-08-12
user4,https://blog.csdn.net/qq_28680977/article/details/108161655?k1=v1&k2=v2#Ref1,10,2020-04-12 11:20:22,2020-04-12
user4,https://blog.csdn.net/qq_28680977/article/details/108161655?k1=v1&k2=v2#Ref1,30,2020-03-12 10:20:22,2020-03-12
user4,https://blog.csdn.net/qq_28680977/article/details/108161655?k1=v1&k2=v2#Ref1,20,2020-02-12 20:26:43,2020-02-12
user2,https://blog.csdn.net/qq_28680977/article/details/108161655?k1=v1&k2=v2#Ref1,10,2020-04-12 19:12:36,2020-04-12
user2,https://blog.csdn.net/qq_28680977/article/details/108161655?k1=v1&k2=v2#Ref1,40,2020-05-12 18:24:31,2020-05-12
建表語句
create table wedw_tmp.tmp_url_info(
user_id string comment "用戶id",
visit_url string comment "訪問url",
visit_cnt int comment "瀏覽次數/pv",
visit_time timestamp comment "瀏覽時間",
visit_date string comment "瀏覽日期"
)
row format delimited
fields terminated by ','
stored as textfile;
窗口函數
row_number:使用頻率 ★★★★★
row_number函數通常用于分組統計組內的排名,然后進行后續的邏輯處理。
注意:當遇到相同排名的時候,不會生成同樣的序號,且中間不會空位
-- 統計每個用戶每天最近一次訪問記錄
select
user_id,
visit_time,
visit_cnt
from
(
select
*,
row_number() over(partition by user_id,visit_date order by visit_time desc) as rank
from wedw_tmp.tmp_url_info
)t
where rank=1
order by user_id,visit_time
+----------+------------------------+------------+--+
| user_id | visit_time | visit_cnt |
+----------+------------------------+------------+--+
| user1 | 2020-08-12 19:20:22.0 | 5 |
| user1 | 2020-09-10 08:19:22.0 | 4 |
| user1 | 2020-09-11 11:20:12.0 | 2 |
| user1 | 2020-09-12 02:20:02.0 | 10 |
| user2 | 2020-04-04 12:23:22.0 | 29 |
| user2 | 2020-04-12 19:12:36.0 | 10 |
| user2 | 2020-05-12 18:24:31.0 | 40 |
| user2 | 2020-05-15 13:34:23.0 | 30 | --該用戶同一天訪問了多次,但只取了最新一次訪問記錄
| user2 | 2020-05-16 19:03:32.0 | 19 |
| user2 | 2020-05-17 06:20:22.0 | 10 |
| user3 | 2020-04-12 08:02:22.0 | 43 |
| user3 | 2020-08-02 10:10:22.0 | 6 |
| user3 | 2020-08-12 12:23:22.0 | 50 |
| user4 | 2020-02-12 20:26:43.0 | 20 |
| user4 | 2020-03-12 10:20:22.0 | 30 |
| user4 | 2020-04-12 11:20:22.0 | 10 |
+----------+------------------------+------------+--+
rank :使用頻率 ★★★★
和row_number功能一樣,都是分組內統計排名,但是當出現同樣排名的時候,中間會出現空位。這里給一個例子就可以很容易理解了
select
user_id,
visit_time,
visit_date,
rank() over(partition by user_id order by visit_date desc) as rank --每個用戶按照訪問時間倒排,通常用于統計用戶最近一天的訪問記錄
from wedw_tmp.tmp_url_info
order by user_id,rank
+----------+------------------------+-------------+-------+--+
| user_id | visit_time | visit_date | rank |
+----------+------------------------+-------------+-------+--+
| user1 | 2020-09-12 02:20:02.0 | 2020-09-12 | 1 |
| user1 | 2020-09-12 02:20:02.0 | 2020-09-12 | 1 | --同一天訪問了兩次,9月11號訪問排名第三
| user1 | 2020-09-11 11:20:12.0 | 2020-09-11 | 3 |
| user1 | 2020-09-10 08:19:22.0 | 2020-09-10 | 4 |
| user1 | 2020-08-12 19:20:22.0 | 2020-08-12 | 5 |
| user2 | 2020-05-17 06:20:22.0 | 2020-05-17 | 1 |
| user2 | 2020-05-16 19:03:32.0 | 2020-05-16 | 2 |
| user2 | 2020-05-15 12:34:23.0 | 2020-05-15 | 3 |
| user2 | 2020-05-15 13:34:23.0 | 2020-05-15 | 3 |
| user2 | 2020-05-12 18:24:31.0 | 2020-05-12 | 5 |
| user2 | 2020-04-12 19:12:36.0 | 2020-04-12 | 6 |
| user2 | 2020-04-04 12:23:22.0 | 2020-04-04 | 7 |
| user3 | 2020-08-12 12:23:22.0 | 2020-08-12 | 1 |
| user3 | 2020-08-02 08:10:22.0 | 2020-08-02 | 2 |
| user3 | 2020-08-02 10:10:22.0 | 2020-08-02 | 2 |
| user3 | 2020-04-12 08:02:22.0 | 2020-04-12 | 4 |
| user4 | 2020-04-12 11:20:22.0 | 2020-04-12 | 1 |
| user4 | 2020-03-12 10:20:22.0 | 2020-03-12 | 2 |
| user4 | 2020-02-12 20:26:43.0 | 2020-02-12 | 3 |
+----------+------------------------+-------------+-------+--+
dense_rank:使用頻率 ★★★★
和row_number以及rank功能一樣,都是分組排名,但是該排名如果出現同次序的話,中間不會留下空位
--還是以rank的sql為例子
select
user_id,
visit_time,
visit_date,
dense_rank() over(partition by user_id order by visit_date desc) as rank
from wedw_tmp.tmp_url_info
order by user_id,rank
+----------+------------------------+-------------+-------+--+
| user_id | visit_time | visit_date | rank |
+----------+------------------------+-------------+-------+--+
| user1 | 2020-09-12 02:20:02.0 | 2020-09-12 | 1 |
| user1 | 2020-09-12 02:20:02.0 | 2020-09-12 | 1 |
| user1 | 2020-09-11 11:20:12.0 | 2020-09-11 | 2 |--中間不會留下空缺
| user1 | 2020-09-10 08:19:22.0 | 2020-09-10 | 3 |
| user1 | 2020-08-12 19:20:22.0 | 2020-08-12 | 4 |
| user2 | 2020-05-17 06:20:22.0 | 2020-05-17 | 1 |
| user2 | 2020-05-16 19:03:32.0 | 2020-05-16 | 2 |
| user2 | 2020-05-15 12:34:23.0 | 2020-05-15 | 3 |
| user2 | 2020-05-15 13:34:23.0 | 2020-05-15 | 3 |
| user2 | 2020-05-12 18:24:31.0 | 2020-05-12 | 4 |
| user2 | 2020-04-12 19:12:36.0 | 2020-04-12 | 5 |
| user2 | 2020-04-04 12:23:22.0 | 2020-04-04 | 6 |
| user3 | 2020-08-12 12:23:22.0 | 2020-08-12 | 1 |
| user3 | 2020-08-02 08:10:22.0 | 2020-08-02 | 2 |
| user3 | 2020-08-02 10:10:22.0 | 2020-08-02 | 2 |
| user3 | 2020-04-12 08:02:22.0 | 2020-04-12 | 3 |
| user4 | 2020-04-12 11:20:22.0 | 2020-04-12 | 1 |
| user4 | 2020-03-12 10:20:22.0 | 2020-03-12 | 2 |
| user4 | 2020-02-12 20:26:43.0 | 2020-02-12 | 3 |
+----------+------------------------+-------------+-------+--+
rank/dense_rank/row_number對比
相同點:都是分組排序
不同點:
- Row_number:即便出現相同的排序,排名也不會一致,只會進行累加;即排序次序連續,但不會出現同一排名
- rank:當出現相同的排序時,中間會出現一個空缺,即分組內會出現同一個排名,但是排名次序是不連續的
- Dense_rank:當出現相同排序時,中間不會出現空缺,即分組內可能會出現同樣的次序,且排序名次是連續的
first_value:使用頻率 ★★★
按照分組排序取截止到當前行的第一個值;通常用于取最新記錄或者最早的記錄(根據排序字段進行變通即可)
--仍然使用row_number的例子;方便讀者理解
select
user_id,
visit_time,
visit_cnt,
first_value(visit_time) over(partition by user_id order by visit_date desc) as first_value_time,
row_number() over(partition by user_id order by visit_date desc) as rank
from wedw_tmp.tmp_url_info
order by user_id,rank
last_value:使用頻率 ★
按照分組排序取當前行的最后一個值;這個函數好像沒啥卵用
--仍然使用row_number的例子;方便讀者理解
select
user_id,
visit_time,
visit_cnt,
last_value(visit_time) over(partition by user_id order by visit_date desc) as first_value_time,
row_number() over(partition by user_id order by visit_date desc) as rank
from wedw_tmp.tmp_url_info
order by user_id,rank
lead:使用頻率 ★★
LEAD(col,n,DEFAULT)用于取窗口內往下第n行值;通常用于行值填充;或者和指定行進行差值比較
第一個參數為列名
第二個參數為往下第n行(可選),
第三個參數為默認值(當往下第n行為NULL時候,取默認值,如不指定,則為NULL)
select
user_id,
visit_time,
visit_cnt,
row_number() over(partition by user_id order by visit_date desc) as rank,
lead(visit_time,1,'1700-01-01') over(partition by user_id order by visit_date desc) as lead_time
from wedw_tmp.tmp_url_info
order by user_id
+----------+------------------------+------------+-------+------------------------+--+
| user_id | visit_time | visit_cnt | rank | lead_time |
+----------+------------------------+------------+-------+------------------------+--+
| user1 | 2020-09-12 02:20:02.0 | 10 | 1 | 2020-09-12 02:20:02.0 | --取下一行的值作為當前值
| user1 | 2020-09-12 02:20:02.0 | 10 | 2 | 2020-09-11 11:20:12.0 |
| user1 | 2020-09-11 11:20:12.0 | 2 | 3 | 2020-09-10 08:19:22.0 |
| user1 | 2020-09-10 08:19:22.0 | 4 | 4 | 2020-08-12 19:20:22.0 |
| user1 | 2020-08-12 19:20:22.0 | 5 | 5 | 1700-01-01 00:00:00.0 | --這里是最后一條記錄,則取默認值
| user2 | 2020-05-17 06:20:22.0 | 10 | 1 | 2020-05-16 19:03:32.0 |
| user2 | 2020-05-16 19:03:32.0 | 19 | 2 | 2020-05-15 12:34:23.0 |
| user2 | 2020-05-15 12:34:23.0 | 30 | 3 | 2020-05-15 13:34:23.0 |
| user2 | 2020-05-15 13:34:23.0 | 30 | 4 | 2020-05-12 18:24:31.0 |
| user2 | 2020-05-12 18:24:31.0 | 40 | 5 | 2020-04-12 19:12:36.0 |
| user2 | 2020-04-12 19:12:36.0 | 10 | 6 | 2020-04-04 12:23:22.0 |
| user2 | 2020-04-04 12:23:22.0 | 29 | 7 | 1700-01-01 00:00:00.0 |
| user3 | 2020-08-12 12:23:22.0 | 50 | 1 | 2020-08-02 08:10:22.0 |
| user3 | 2020-08-02 08:10:22.0 | 5 | 2 | 2020-08-02 10:10:22.0 |
| user3 | 2020-08-02 10:10:22.0 | 6 | 3 | 2020-04-12 08:02:22.0 |
| user3 | 2020-04-12 08:02:22.0 | 43 | 4 | 1700-01-01 00:00:00.0 |
| user4 | 2020-04-12 11:20:22.0 | 10 | 1 | 2020-03-12 10:20:22.0 |
| user4 | 2020-03-12 10:20:22.0 | 30 | 2 | 2020-02-12 20:26:43.0 |
| user4 | 2020-02-12 20:26:43.0 | 20 | 3 | 1700-01-01 00:00:00.0 |
+----------+------------------------+------------+-------+------------------------+--+
lag:使用頻率 ★★
和lead功能一樣,但是是取上n行的值作為當前行值
select
user_id,
visit_time,
visit_cnt,
row_number() over(partition by user_id order by visit_date desc) as rank,
lag(visit_time,1,'1700-01-01') over(partition by user_id order by visit_date desc) as lead_time
from wedw_tmp.tmp_url_info
order by user_id
集合相關
collect_set:使用頻率 ★★★★★
將分組內的數據放入到一個集合中,具有去重的功能;
--統計每個用戶具體哪些天訪問過
select
user_id,
collect_set(visit_date) over(partition by user_id) as visit_date_set
from wedw_tmp.tmp_url_info
collect_list:使用頻率 ★★★★★
和collect_set一樣,但是沒有去重功能
select
user_id,
collect_set(visit_date) over(partition by user_id) as visit_date_set
from wedw_tmp.tmp_url_info
--如下圖可見,user2在2020-05-15號多次訪問,這里也算進去了
sort_array:使用頻率 ★★★
數組內排序;通常結合collect_set或者collect_list使用;
如collect_list為例子,可以發現日期并不是按照順序組合的,這里有需求需要按照時間升序的方式來組合
--按照時間升序來組合
select
user_id,
sort_array(collect_list(visit_date) over(partition by user_id)) as visit_date_set
from wedw_tmp.tmp_url_info
--結果如下圖所示;
如果突然業務方改需求了,想要按照時間降序來組合,那基于上面的sql該如何變通呢?哈哈哈哈,其實沒那么復雜,這里根據沒必要按照sort_array來實現,在collect_list中的分組函數內直接按照visit_date降序即可,這里只是為了演示sort_array如何使用
--按照時間降序排序
select
user_id,
collect_list(visit_date) over(partition by user_id order by visit_date desc) as visit_date_set
from wedw_tmp.tmp_url_info
這里還有一個小技巧,對于數值類型統計多列或者數組內的最大值,可以使用sort_array來實現
--具體思路就是先把數值變成負數,然后升序排序即可
select -sort_array(array(-a,-b,-c))[0] as max_value
from (
select 1 as a, 3 as b, 2 as c
) as data
+------------+--+
| max_value |
+------------+--+
| 3 |
+------------+--+
URL相關
parse_url:使用頻率 ★★★★
用于解析url相關的參數,直接上sql
select
visit_url,
parse_url(visit_url, 'HOST') as url_host, --解析host
parse_url(visit_url, 'PATH') as url_path, --解析path
parse_url(visit_url, 'QUERY') as url_query,--解析請求參數
parse_url(visit_url, 'REF') as url_ref, --解析ref
parse_url(visit_url, 'PROTOCOL') as url_protocol, --解析協議
parse_url(visit_url, 'AUTHORITY') as url_authority,--解析author
parse_url(visit_url, 'FILE') as url_file, --解析filepath
parse_url(visit_url, 'USERINFO') as url_user_info --解析userinfo
from wedw_tmp.tmp_url_info
reflect:使用頻率 ★★
該函數是利用java的反射來實現一些功能,目前筆者只用到了關于url編解碼
--url編碼
select
visit_url,
reflect("java.net.URLEncoder", "encode", visit_url, "UTF-8") as visit_url_encode
from wedw_tmp.tmp_url_info
--url解碼
select
visit_url,
reflect("java.net.URLDecoder", "decode", visit_url_encode, "UTF-8") as visit_url_decode
from
(
select
visit_url,
reflect("java.net.URLEncoder", "encode", visit_url, "UTF-8") as visit_url_encode
from wedw_tmp.tmp_url_info
)t
JSON相關
get_json_object:使用頻率 ★★★★★
通常用于獲取json字符串中的key,如果不存在則返回null
select
get_json_object(json_data,'$.user_id') as user_id,
get_json_object(json_data,'$.age') as age --不存在age,則返回null
from
(
select
concat('{"user_id":"',user_id,'"}') as json_data
from wedw_tmp.tmp_url_info
)t
列轉行相關
explode:使用頻率 ★★★★★
列轉行,通常是將一個數組內的元素打開,拆成多行
--簡單例子
select explode(array(1,2,3,4,5))
+------+--+
| col |
+------+--+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+------+-
--結合lateral view 使用
select
get_json_object(user,'$.user_id')
from
(
select
distinct collect_set(concat('{"user_id":"',user_id,'"}')) over(partition by year(visit_date)) as user_list
from wedw_tmp.tmp_url_info
)t
lateral view explode(user_list) user_list as user
Cube相關
GROUPING SETS:使用頻率 ★
類似于kylin中的cube,將多種維度進行組合統計;在一個GROUP BY查詢中,根據不同維度組合進行聚合,等價于將不同維度的GROUP BY結果集進行UNION ALL
--按照用戶+訪問日期統計統計次數
select
user_id,
visit_date,
sum(visit_cnt) as visit_cnt
from wedw_tmp.tmp_url_info
group by user_id,visit_date
grouping sets(user_id,visit_date)
--下圖的結果類似于以下sql
select
user_id,
NULL as visit_date,
sum(visit_cnt) as visit_cnt
from wedw_tmp.tmp_url_info
union all
select
NULL as user_id,
visit_date,
sum(visit_cnt) as visit_cnt
from wedw_tmp.tmp_url_info
union all
select
user_id,
visit_date,
sum(visit_cnt) as visit_cnt
from wedw_tmp.tmp_url_info
字符相關
concat:使用頻率 ★★★★★
字符拼接,concat(string|binary A, string|binary B...);該函數比較簡單
select concat('a','b','c')
--最后結果就是abc
concat_ws:使用頻率 ★★★★★
按照指定分隔符將字符或者數組進行拼接;concat_ws(string SEP, array<string>)/concat_ws(string SEP, string A, string B...)
--還是concat使用的例子,這里可以寫成
select concat_ws('','a','b','c')
--將數組列表元素按照指定分隔符拼接,類似于python中的join方法
select concat_ws('',array('a','b','c'))
instr:使用頻率 ★★★★
查找字符串str中子字符串substr出現的位置,如果查找失敗將返回0,如果任一參數為Null將返回null,注意位置為從1開始的;通常筆者用這個函數作為模糊查詢來查詢
--查詢vist_time包含10的記錄
select
user_id,
visit_time,
visit_date,
visit_cnt
from wedw_tmp.tmp_url_info
where instr(visit_time,'10')>0
length:使用頻率 ★★★★★
統計字符串的長度
select length('abc')
size:使用頻率 ★★★★★
是用來統計數組或者map的元素,通常筆者用該函數用來統計去重數(一般都是通過distinct,然后count統計,但是這種方式效率較慢)
--使用size
select
distinct size(collect_set(user_id) over(partition by year(visit_date)))
from wedw_tmp.tmp_url_info
+-----------+--+
| user_cnt |
+-----------+--+
| 4 |
+-----------+--+
1 row selected (0.268 seconds)
--使用通過distinct,然后count統計的方式
select
count(1)
from
(
select
distinct user_id
from wedw_tmp.tmp_url_info
)t
+-----------+--+
| count(1) |
+-----------+--+
| 4 |
+-----------+--+
1 row selected (0.661 seconds)
--筆者這里只用到了19條記錄數,就可以明顯觀察到耗時差異,這里涉及到shuffle問題,后續將會有單獨的文章來講解hive的數據傾斜問題
trim:使用頻率 ★★★★★
將字符串前后的空格去掉,和java中的trim方法一樣,這里還有ltrim和rtrim,不再講述了
--最后會得到sfssf sdf sdfds
select trim(' sfssf sdf sdfds ')
regexp_replace:使用頻率 ★★★★★
regexp_replace(string INITIAL_STRING, string PATTERN, string REPLACEMENT)
按照Java正則表達式PATTERN將字符串中符合條件的部分成REPLACEMENT所指定的字符串,如里REPLACEMENT空的話,抽符合正則的部分將被去掉
--將url中?參數后面的內容全部剔除
select
distinct regexp_replace(visit_url,'\\?(.*)','') as visit_url
from wedw_tmp.tmp_url_info
regexp_extract:使用頻率 ★★★★
regexp_extract(string subject, string pattern, int index)
抽取字符串subject中符合正則表達式pattern的第index個部分的子字符串,注意些預定義字符的使用
類型于python爬蟲中的xpath,用于提取指定的內容
--提取csdn文章編號
select
distinct regexp_extract(visit_url,'/details/([0-9]+)',1) as visit_url
from wedw_tmp.tmp_url_info
substring_index:使用頻率 ★★
substring_index(string A, string delim, int count)
截取第count分隔符之前的字符串,如count為正則從左邊開始截取,如果為負則從右邊開始截取
--比如將2020年的用戶組合獲取前2個用戶,下面的sql將上面講解的函數都結合在一起使用了
select
user_set,
substring_index(user_set,',',2) as user_id
from
(
select
distinct concat_ws(',',collect_set(user_id) over(partition by year(visit_date))) as user_set
from wedw_tmp.tmp_url_info
)t
條件判斷
if:使用頻率 ★★★★★
if(boolean testCondition, T valueTrue, T valueFalseOrNull):判斷函數,很簡單
如果testCondition 為true就返回valueTrue,否則返回valueFalseOrNull
--判斷是否為user1用戶
select
distinct user_id,
if(user_id='user1',true,false) as flag
from wedw_tmp.tmp_url_info
case when :使用頻率 ★★★★★
CASE a WHEN b THEN c [WHEN d THEN e] [ELSE f] END
如果a=b就返回c,a=d就返回e,否則返回f 如CASE 4 WHEN 5 THEN 5 WHEN 4 THEN 4 ELSE 3 END 將返回4
相比if,個人更傾向于使用case when
--仍然以if上面的列子
select
distinct user_id,
case when user_id='user1' then 'true'
when user_id='user2' then 'test'
else 'false' end as flag
from wedw_tmp.tmp_url_info
coalesce:使用頻率 ★★★★★
COALESCE(T v1, T v2, ...)
返回第一非null的值,如果全部都為NULL就返回NULL
--該函數結合lead或者lag更容易貼近實際業務需求,這里使用lead,并取后3行的值作為當前行值
select
user_id,
visit_time,
rank,
lead_time,
coalesce(visit_time,lead_time) as has_time
from
(
select
user_id,
visit_time,
visit_cnt,
row_number() over(partition by user_id order by visit_date desc) as rank,
lead(visit_time,3) over(partition by user_id order by visit_date desc) as lead_time
from wedw_tmp.tmp_url_info
order by user_id
)t
數值相關
round:使用頻率 ★★
round(DOUBLE a):返回對a四舍五入的BIGINT值,
round(DOUBLE a, INT d):返回DOUBLE型d的保留n位小數的DOUBLW型的近似值
該函數沒什么可以講解的
select round(4/3),round(4/3,2);
+------+-------+--+
| _c0 | _c1 |
+------+-------+--+
| 1.0 | 1.33 |
+------+-------+--+
ceil:使用頻率 ★★★
ceil(DOUBLE a), ceiling(DOUBLE a)
求其不小于小給定實數的最小整數;向上取整
select ceil(4/3),ceiling(4/3)
floor:使用頻率 ★★★
floor(DOUBLE a):向下取整''
select floor(4/3);
hex:使用頻率 ★
hex(BIGINT a)/ hex(STRING a)/ hex(BINARY a)
計算十六進制a的STRING類型,如果a為STRING類型就轉換成字符相對應的十六進制
該函數很少使用,主要是因為曾經遇到過關于emoj表情符臟數據,故使用該函數進行處理
時間相關(比較簡單)
from_unxitime:使用頻率 ★★★★★
from_unixtime(bigint unixtime[, string format])
將時間的秒值轉換成format格式(format可為“yyyy-MM-dd hh:mm:ss”,“yyyy-MM-dd hh”,“yyyy-MM-dd hh:mm”等等)
select from_unixtime(1599898989,'yyyy-MM-dd') as current_time
+---------------+--+
| current_time |
+---------------+--+
| 2020-09-12 |
+---------------+--+
unix_timestamp:使用頻率 ★★★★★
unix_timestamp():獲取當前時間戳
unix_timestamp(string date):獲取指定時間對應的時間戳
通過該函數結合from_unixtime使用,或者可計算兩個時間差等
select
unix_timestamp() as current_timestamp,--獲取當前時間戳
unix_timestamp('2020-09-01 12:03:22') as speical_timestamp,--指定時間對于的時間戳
from_unixtime(unix_timestamp(),'yyyy-MM-dd') as current_date --獲取當前日期
to_date:使用頻率 ★★★★★
to_date(string timestamp)
返回時間字符串的日期部分
--最后得到2020-09-10
select to_date('2020-09-10 10:31:31')
year:使用頻率 ★★★★★
year(string date)
返回時間字符串的年份部分
--最后得到2020
select year('2020-09-02')
month:使用頻率 ★★★★★
month(string date)
返回時間字符串的月份部分
--最后得到09
select month('2020-09-10')
day:使用頻率 ★★★★★
day(string date)
返回時間字符串的天
--最后得到10
select day('2002-09-10')
date_add:使用頻率 ★★★★★
date_add(string startdate, int days)
從開始時間startdate加上days
--獲取當前時間下未來一周的時間
select date_add(now(),7)
--獲取上周的時間
select date_add(now(),-7)
date_sub:使用頻率 ★★★★★
date_sub(string startdate, int days)
從開始時間startdate減去days
--獲取當前時間下未來一周的時間
select date_sub(now(),-7)
--獲取上周的時間
select date_sub(now(),7)