知識點一:
explode(split(get_json_object(fieldDataName,’$.str’),’,’))
1、fieldDataName表示數據庫字段名;
2、$.str表示要從數據庫定中JOSN類型的字段中取的內容
使用到的命令包括:
1、get_json_object :從JSON中取值;
get_json_object,多層JSON的取值
data =
{
"store":
{
"fruit":[{"weight":8,"type":"apple"}, {"weight":9,"type":"pear"}],
"bicycle":{"price":19.95,"color":"red"}
},
"email":"amy@only_for_json_udf_test.net",
"owner":"amy"
}
1.1、.get單層值
hive> select get_json_object(data, ‘$.owner’) from test;
結果:amy
1.2.get多層值.
hive> select get_json_object(data, ‘$.store.bicycle.price’) from test;
結果:19.95
1.3.get數組值[]
hive> select get_json_object(data, ‘$.store.fruit[0]’) from test;
結果:{“weight”:8,“type”:“apple”}
2、split:按,號分隔
split中使用多個分隔符的示例:
select split('張三|李四,王五|趙六',',|\\|')
多個分隔符使用“|”號進行連接。在上面的例子中,第一個分隔符是“,”,第二個分隔符是“\|”,因爲本身多個分隔符就是使用|連接的,所以需要加\用來轉義
3、explode:explode就是將hive一行中複雜的array或者map結構拆分成多行。explode可能經常會與Lateralview一起使用
4、Lateral view: 其實就是用來和像類似explode這種UDTF函數聯用的。lateral view 會將UDTF生成的結果放到一個虛擬表中,然後這個虛擬表會和輸入行即每個game_id進行join 來達到連接UDTF外的select字段的目的。
示例:
select distinct course,student1 From courselog lateral view explode(split(get_json_object(data,’$.student’),’,’)) t as student1
where area=‘310000’ and log_date>=‘2018-11-01’ and student1<>’[]’
知識點二: HVIE中配合正則表達式的使用
例如:需要將[“張三”,“李四”]中學生名字取出來。
如果直接使用select explode(split('["張三","李四"]',','))
,得出的結果就是:
[“張三”
“李四”]
這並不是我們希望得到的結果。希望的結果應該是不包括雙引號,不包括中括號的。使用正則表達式對字符進行處理:
select explode(split(regexp_extract('["張三","李四"]','\\[(.+)\\]',1),','))
以上得到的結果就是去除[]的結果。
但是其實我們還是希望把雙引號也去掉的。上面我們是希望把以下字符串([]")替換掉就可以了,發現可以使用以下命令來處理:
select regexp_replace('["張三","李四"]','"|\\[|\\]','')
這個得到的結果就是:張三,李四
到這一步再結合explode就可以達到效果了:
select explode(split(regexp_replace('["張三","李四"]','"|\\[|\\]',''),','))
這樣得到的結果就是:
張三
李四
知識點三:關於HIVE裏面進行時間戮和日期格式的轉換:
from_unixtime(時間戮,日期格式),日期格式如果不指定,默認是’yyyy-MM-dd HH:mm:ss’
如果我們存儲的時間戮格式是到毫秒的,需要將最後三位去掉,使用cast進行類型轉換。
例如:from_unixtime(cast(t.time/1000 as int),‘yyyy-MM-dd’)
知識點四:根據一定的條件分組,並返回分組中最新(也可以是值最大)的一條記錄
感謝:toto1297488504的博客講解得比較清楚
命題:從表中查找每科成績最好的一名學生(表名:s_score)
id | sname | cno | score |
---|---|---|---|
1 | A | 數學 | 80 |
2 | B | 數學 | 82 |
3 | C | 數學 | 89 |
4 | A | 語文 | 80 |
5 | B | 語文 | 60 |
6 | C | 語文 | 70 |
語句如下:
select t.sname,t.cno,t.score from (select sname,cno,score,ROW_NUMBER() OVER(PARTITION BY cno ORDER BY score desc) AS rn FROM s_score
#where 條件(我們這個命題中沒有,需要的根據實際增加)#) t where t.rn=1;
解釋:
ROW_NUMBER() OVER(PARTITION BY cno ORDER BY score desc) AS rn
這一句是比較關鍵的,表示:根據cno進行分區,然後在每個分區裏面按score進行倒序。這一句明白了,那面如果最成績最好的2名學生,就是t.rn<=2就可以了