hive sql 學習筆記


1、coalesce

    語法:

COALESCE ( expression [ ,...n ] )   

  參數:

  expression 任何類型的表達式。

  返回類型:

  返回數據類型優先級最高的 expression 的數據類型。 如果所有表達式都不可為 Null,則結果的類型也不可為 Null。

  備注
 
   如果所有參數均為 NULL,則 COALESCE 返回 NULL。 至少應有一個 Null 值為 NULL 類型。
 

COALESCE 表達式是 CASE 表達式的語法快捷方式。 即查詢優化器將代碼 COALESCE(expression1,...n) 重寫為以下 CASE 表達式:

CASE

WHEN (expression1 IS NOT NULL) THEN expression1

WHEN (expression2 IS NOT NULL) THEN expression2

...

ELSE expressionN

END

這意味着將多次計算輸入值(expression1expression2expressionN 等)。 此外,為了符合 SQL 標准,包含子查詢的值表達式被視為不確定的且子查詢被計算兩次。 在每種情況中,第一次計算和后續計算可能返回不同的結果。

 

2、having子句

  sql中having子句與where子句類似,都是表示條件的設定,它們的區別在於,having子句在查詢過程中慢於聚合語句(sum,min,max,avg,count);而where子句在查詢過程中則快於聚合語句(sum,min,max,avg,count)。

  簡單說來:  

  where子句:  
  select sum(num) as rmb from order where id>10  
  //先查詢出id大於10的記錄才能進行聚合語句  

  having子句:  
  select reportsto as manager, count(*) as reports from employees  
  group by reportsto having count(*) > 4  

  //having的條件表達式count()是一個聚合語句,因此having的執行一定慢於聚合語句count,如果換成where則會出錯。

  //統計分組數據時用到聚合語句,對分組數據再次判斷時要用having。如果不用這些關系就不存在使用having。直接使用where就行了。  

  having就是來彌補where在分組數據判斷時的不足。因為where要快於聚合語句。

 

  如果你對何時應該使用WHERE,何時使用HAVING仍舊很迷惑,請遵照下面的說明:   

  WHERE語句在GROUP BY語句之前;SQL會在分組之前計算WHERE語句。   

  HAVING語句在GROUP BY語句之后;SQL會在分組之后計算HAVING語句。

3、mapjoin

使用MAPJOIN時,需要注意:
1、LEFT OUTER JOIN的左表必須是大表;
2、RIGHT OUTER JOIN的右表必須是大表;
3、INNER JOIN左表或右表均可以作為大表;
4、FULL OUTER JOIN不能使用MAPJOIN;
5、MAPJOIN支持小表為子查詢;
6、使用MAPJOIN時需要引用小表或是子查詢時,需要引用別名;
7、在MAPJOIN中,可以使用不等值連接或者使用OR連接多個條件;

  mapjoin里寫的是小表,且left outer join時小表寫在join的后面;

  hive中使用mapjoin有時可以大大提高sql語句的執行效率。

  其原理是:它會把小表全部讀入內存中,在map的時候直接拿另外一張表的數據和內存中表的數據做匹配,進行join操作,這樣省去了reduce。

  (1)在“關聯操作中有一個表非常小,另一個表很大”的場景下,mapjoin就不會由於數據傾斜而導致某個reduce上落數據太多而失敗;

  例子:

SELECT  /*+ MAPJOIN(b) */  a.key, a.value
FROM a JOIN b ON a.key = b.key
  • does not need a reducer. For every mapper of A, B is read completely. The restriction is that a FULL/RIGHT OUTER JOIN b cannot be performed.

(2)在需要進行“不等值連接操作”的場景中(如a.x<b.y 或 a.x like b.y 等),由於where子句中的不等值join操作產生笛卡爾積,引起數據異常增大,速度會變慢;而mapjoin則可以提高此操作的效率,即使遇到笛卡爾積也不會對運行速度帶來太大影響;

  例子:

  

select /*+ MAPJOIN(a) */
  a.start_level, b.*
 from dim_level a
  join (select * from test) b
 where b.xx>=a.start_level and b.xx<end_level;

  在同時需要進行大小表關聯和不等值關聯的情景下,用mapjoin會有更明顯的效果,尤其是大表數據傾斜比較嚴重的時候。

  例子:

  使用mapjoin前:

create table hive_no_mapjoin as 

  select f.id,f.dt, coalesce(k.amt,0.0) amt from(

  select a.id,t.dt from hive_dt t join (select id, min(dt) min_dt from hive_mapjoin group by id) a
  where t.dt>= a.min_dt) f 
  left outer join hive_mapjoin k on f.dt = k.dt and f.id = k.id;

  使用mapjoin后:

create table hive_ok_mapjoin as select f.id,f.dt, coalesce(k.amt,0.0) amt from(

select /*+ mapjoin(t) */ a.id,t.dtfrom hive_dt t 
join (

select id,  min(dt) min_dt from hive_mapjoin group by id) a 
where  t.dt>= a.min_dt) f 
left outer join tmp.tst1 kon f.dt = k.dt and f.id = k.id;

  友情鏈接:http://www.cnblogs.com/tmeily/p/4250858.html

       http://www.ithao123.cn/content-579190.html

 

4、hive中,group by 需要比較多的reduce , order by rand()需要比較多的map reduce,所以當數據量比較大的時候,如果這兩個動作同時執行,會很耗資源,解決的辦法是分成兩步,先order by rand() limit n 取出來,然后再從這個結果里面group by;

 

5、hive中,需要select 多個字段,但只要distinct某個字段並列出它的值,可以用:

select cid,count(distinct cid) from credit.vec_sim_pairs where dt=${CUR_DATE} and cid!='0' group by cid;
忽略count(distinct cid)這一列就可以了。
參考來源:http://www.jb51.net/article/24717.htm
 
6、查看某個表的某個分區的hdfs路徑 語句:
use database;
show table extended like table_name partition(dt='%Y%m%d')
 
7、隨機抽樣的語句:(1)select * from tablename TABLESAMPLE(n PERCENT|ROWS|ByteLengthLiteral ) where ……
其中,n percent將會抽取 n%的比例數據 (但是這種方法結果出來的數據並沒有真的是按比例抽取)
         (2) select * from my_table distribute by rand() sort by rand() limit 10000;(親測可靠)
 
參考:http://www.joefkelley.com/736/
   http://www.aichengxu.com/other/9663663.htm
     http://lxw1234.com/archives/2015/08/444.htm
8、hive中字段類型轉換
  cast(field as type)
或者:
  convert(field,type)
 
 9、explain
  使用explain可以查看hql語句運行的詳細信息;
例如:
explain select a.key c1, a.value c2, b.key c3, b.value c4 from src a join src_skewjoin1 b on a.key = b.key;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM