數倉利器-Hive高頻函數合集

前言

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對比

相同點:都是分組排序

不同點:

  1. Row_number:即便出現相同的排序,排名也不會一致,只會進行累加;即排序次序連續,但不會出現同一排名
  2. rank:當出現相同的排序時,中間會出現一個空缺,即分組內會出現同一個排名,但是排名次序是不連續的
  3. 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
1.png

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
2.png

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
3.png

集合相關

collect_set:使用頻率 ★★★★★

將分組內的數據放入到一個集合中,具有去重的功能;

--統計每個用戶具體哪些天訪問過
select
  user_id,
  collect_set(visit_date) over(partition by user_id) as visit_date_set 
from wedw_tmp.tmp_url_info

4.png

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號多次訪問,這里也算進去了
6.png

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
--結果如下圖所示;
1.png

如果突然業務方改需求了,想要按照時間降序來組合,那基于上面的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
2.png

這里還有一個小技巧,對于數值類型統計多列或者數組內的最大值,可以使用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
3.png

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
4.png
--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
5.png

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
6.png

列轉行相關

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
7.png

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
8.png

字符相關

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
9.png

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
10.png

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 
11.png

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
12.png

條件判斷

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 
13.png

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 
14.png

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
15.png

數值相關

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)
16.png

floor:使用頻率 ★★★

floor(DOUBLE a):向下取整''

select floor(4/3);
17.png

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 --獲取當前日期
18.png

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)
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,572評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,071評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,409評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,569評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,360評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,895評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,979評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,123評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,643評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,559評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,742評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,250評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,981評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,363評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,622評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,354評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,707評論 2 370