注意
多表关联必须选择 不为null的值进行关联
需要函数: nvl
coalesce
不使用的全外联的优化方法(全为数字类型的表可以这样做):
将字段补零,union,然后分组聚合
电商数据仓库系统
第6章 数仓搭建-DWD层
启动日志表–对应一个启动日志
页面日志表–对应一个页面埋点日志
动作日志表–在一个页面埋点日志会有多个动作
一行数据是一个动作,所以就需要一进多出的操作,UDTF函数
6.1.5 动作日志表装载中定义UDTF函数
动作日志解析思路:动作日志表中每行数据对应用户的一个动作记录,一个动作记录应当包含公共信息、页面信息以及动作信息。先将包含action字段的日志过滤出来,然后通过UDTF函数,将action数组“炸开”(类似于explode函数的效果),然后使用get_json_object函数解析每43个字段。
package com.atguigu.hive.udtf;
import java.util.ArrayList;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorUtils;
import org.json.JSONArray;
/**
* GenericUDTFCount2 outputs the number of rows seen, twice. It's output twice
* to test outputting of rows on close with lateral view.
*
*/
public class ExplodeJOSNArray extends GenericUDTF {
// 为了在 process 中能拿到 initialize传入的数据的ObjectInspector 来声明对象
private PrimitiveObjectInspector inputOI;
@Override
public void close() throws HiveException {
}
@Override
public StructObjectInspector initialize(ObjectInspector[] argOIs) throws UDFArgumentException {
// 第一个功能 校验UDTF输入参数的合法性
if( argOIs.length!=1){
throw new UDFArgumentException("explode_json_array函数只能接收1一个参数");
}
ObjectInspector argOI = argOIs[0];
// 先判断是否是基本数据类型
if(argOI.getCategory()==ObjectInspector.Category.PRIMITIVE){
throw new UDFArgumentException("explode_json_array函数只能接收基本数据类型的参数");
}
// 强转为 PrimitiveObjectInspector类型
PrimitiveObjectInspector primitiveOI = (PrimitiveObjectInspector) argOI;
inputOI=primitiveOI;
// 判断是否是PrimitiveObjectInspector的STRING类型
if(primitiveOI.getPrimitiveCategory()==PrimitiveObjectInspector.PrimitiveCategory.STRING){
throw new UDFArgumentException("explode_json_array函数只能接收STRING类型的参数");
}
// 第二个功能 定义输出格式 列名和对象检查器
ArrayList<String> fieldNames = new ArrayList<String>();
ArrayList<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>();
fieldNames.add("item");
fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
return <