Hive 分組 Limit 非UDF方案

其實前一篇的Mysql 小技巧中having min()的方法是爲了本篇準備的。可是當時遇到南牆,此次終於破壁找到方案。java

描述:  id (自增),type (aaa, bbb,ccc ,ddd),status(ok,error) 三個字段,每一個type,篩選status='ok'的而且id最小的那一條記錄。 mysql

Mysql:

create table having_test (id int(11), type varchar(50),status varchar(50));
mysql> select * from having_test;
+------+------+--------+
| id   | type | status |
+------+------+--------+
|    1 | aaa  | ok     |
|    2 | aaa  | error  |
|    3 | aaa  | ok     |
|    4 | bbb  | ok     |
|    5 | ccc  | error  |
|    6 | ccc  | ok     |
|    7 | ddd  | error  |
+------+------+--------+


mysql> select * from having_test where status='ok' group by type having min(id);
+------+------+--------+
| id   | type | status |
+------+------+--------+
|    1 | aaa  | ok     |
|    4 | bbb  | ok     |
|    6 | ccc  | ok     |
+------+------+--------+

  mysql中很簡單就實現了,先 group 而後having ,可是hive上不是徹底支持sql語法的,在hive上會不會這麼簡單呢,答案是否認的。sql

HIVE 中:

create table tmp_wjk_having_test (id int,  type string, status string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' ;
load data local inpath '/tmp/load.csv' overwrite into table tmp_wjk_having_test;   

select * from tmp_wjk_having_test; 
1    aaa     ok                                                                                                                                        
2    aaa     error                                                                                                                                     
3    aaa     ok                                                                                                                                        
4    bbb     ok                                                                                                                                        
5    ccc     error                                                                                                                                    
6    ccc     ok                                                                                                                                        
7    ddd     error 

select * from tmp_wjk_having_test where status='ok' group by type having min(id);
FAILED: Error in semantic analysis: Line 1:73 Expression not in GROUP BY key 'id'  
# hive 不支持這種寫法。仍是要用子查詢


select * from tmp_wjk_having_test t1 join (
    select min(id) id from tmp_wjk_having_test where status='ok' group by type) t2 
on t1.id=t2.id ; 
1     aaa     ok     1
4     bbb     ok     4
6     ccc     ok     6

子查詢對於小數據集沒有影響,可是應用到大數據上最好的是隻過一邊表,而後就拿出結果。因此還在想新的方案。大數據

select *,min(id) ii from tmp_wjk_having_test where  status='ok'  group by type ;
aaa     1     1
bbb     4     4
ccc     6     6

這種方案可行。問題點:spa

1.  爲何min(id)的條件明明是寫到了select 中非where ,可是確起到了篩選的做用?code

2.  爲何明明是select * ,min(id) 可是最後是拿到了3列(type , id , min(id) ), 若是寫成 select type ,min(id) 就只拿到2列( type ,min(id) )  .string

select type,min(id) ii from tmp_wjk_having_test where  status='ok'  group by type;
aaa     1
bbb     4
ccc     6


++++更新 2014.11.11it

三、通常可行方案:io

2列 : select type,min(id) ii from tmp_wjk_having_test where  status='ok'  group by type;
多列:select t1.* from having_test t1 join (select name,min(age) mm from having_test group by name ) t2 on t1.name = t2.name and t1.age=t2.mm ;
相關文章
相關標籤/搜索