1、UDF:用戶定義(普通)函數,只對單行數值產生作用;
繼承UDF類,添加方法 evaluate()
/** * @function 自定義UDF統計最小值 * @author John * */ public class Min extends UDF { public Double evaluate(Double a, Double b) { if (a == null) a = 0.0; if (b == null) b = 0.0; if (a >= b) { return b; } else { return a; } } }
2、UDAF:User- Defined Aggregation Funcation;用戶定義聚合函數,可對多行數據產生作用;等同與SQL中常用的SUM(),AVG(),也是聚合函數;
聚合函數使用:
SELECT store_name, SUM(sales)
FROM Store_Information
GROUP BY store_name
HAVING SUM(sales) > 1500
ORDER BY SUM(sales);
鍵字HAVING總要放在GROUP BY之后,ORDER BY之前
UDAF實現有簡單與通用兩種方式:
a. 簡單UDAF因為使用Java反射導致性能損失,而且有些特性不能使用,已經被棄用了;
import org.apache.hadoop.hive.ql.exec.UDAF; import org.apache.hadoop.hive.ql.exec.UDAFEvaluator; import org.apache.hadoop.io.IntWritable; //UDAF是輸入多個數據行,產生一個數據行 //用戶自定義的UDAF必須是繼承了UDAF,且內部包含多個實現了exec的靜態類 public class MaxiNumber extends UDAF { public static class MaxiNumberIntUDAFEvaluator implements UDAFEvaluator { // 最終結果 private IntWritable result; // 負責初始化計算函數並設置它的內部狀態,result是存放最終結果的 @Override public void init() { result = null; } // 每次對一個新值進行聚集計算都會調用iterate方法 public boolean iterate(IntWritable value) { if (value == null) return false; if (result == null) result = new IntWritable(value.get()); else result.set(Math.max(result.get(), value.get())); return true; } // Hive需要部分聚集結果的時候會調用該方法 // 會返回一個封裝了聚集計算當前狀態的對象 public IntWritable terminatePartial() { return result; } // 合並兩個部分聚集值會調用這個方法 public boolean merge(IntWritable other) { return iterate(other); } // Hive需要最終聚集結果時候會調用該方法 public IntWritable terminate() { return result; } } }
b. 另一種涉及兩個類:AbstractGenericUDAFResolver、GenericUDAFEvaluator;
繼承UDAFResolver類,重寫 getEvaluator() 方法;
繼承GenericUDAFEvaluator類,生成實例給getEvaluator();
在GenericUDAFEvaluator類中,重寫init()、iterate()、terminatePartial()、merge()、terminate()方法;
3、UDTF:User-Defined Table-Generating Functions,用戶定義表生成函數,用來解決輸入一行輸出多行;
繼承GenericUDTF類,重寫initialize(返回輸出行信息:列個數,類型), process, close三方法;
4、其它
刪除臨時函數 drop temporary function toUpper;
