制作拉链表

    首先初始化拉链表
    通常要在原表的基础上加入start_date,end_date,并从原表导入数据到拉链表
    drop table if exists dwd_order_info_his;

    create external table dwd_order_info_his(
    id string COMMENT ‘订单编号’,
    order_status string COMMENT ‘订单状态’,
    start_date string COMMENT ‘有效开始日期’,
    end_date string COMMENT ‘有效结束日期’
    ) COMMENT ‘订单拉链表’

    创建临时表整个中间数据
    临时表和拉链表表结构一致,只是为了存储中间过程。

    drop table if exists dwd_order_info_his_tmp;
    create external table dwd_order_info_his_tmp(
    id string COMMENT ‘订单编号’,
    order_status string COMMENT ‘订单状态’,
    start_date string COMMENT ‘有效开始日期’,
    end_date string COMMENT ‘有效结束日期’
    ) COMMENT ‘订单拉链临时表’
    向临时表中插入数据
    插入前,拉链表数据

    订单新增表数据

    插入数据后

    订单1和订单2,订单状态都发生了改变,产生了新数据
    具体sql

    insert overwrite table dwd_order_info_his_tmp
    select * from
    (
    select
    id,
    total_amount,
    order_status,
    user_id,
    payment_way,
    out_trade_no,
    create_time,
    operate_time,
    ‘2019-02-14’ start_date, // 分区时间作为开始时间
    ‘9999-99-99’ end_date
    from dwd_order_info where dt=’2019-02-14’
    // 这一部分主要是插入有效的数据数据(包括新增和更新)
    union all
    select oh.id,
    oh.total_amount,
    oh.order_status,
    oh.user_id,
    oh.payment_way,
    oh.out_trade_no,
    oh.create_time,
    oh.operate_time,
    oh.start_date,
    if(oi.id is null, oh.end_date, date_add(oi.dt-1)) end_date

    1、如果没有关联上,则说明 拉链历史表中存在该条记录,新的增量表中没有这条数据,说明这条数据,在这一天没有更改或者变化,这样就没有必要更改这条数据的生命周期时间。
    这样的操作,不会向拉量表新增数据。

    2、如果关联上了,则说明拉链历史表有这条数据,这一天的全量表也有这条数据,于是可以确定这条数据有更新,我们会把拉链历史表中这一条数据置为关闭时间置为这一天,意味着这条数据失效。同时,这一天的全量表中会新增的一条end_date 为9999的数据,这条数据才是有效的。达到的效果就是 新的拉量表中在这一天中,这条数据会新增两条数据,一条是全量中中新增的有效数据,另一条是拉链表中以前有效的数据会变为无效。

    这一部分的数据主要是插入失效的数据,这些数据存在于之前的拉链历史表,需要把已经更新的收据设置为失效,然后插入新的拉量表。

    from dwd_order_info_his oh left join
    (
    select
    *
    from dwd_order_info
    where dt=’2019-02-14’
    ) oi
    on oh.id=oi.id and oh.end_date=’9999-99-99’
    )his
    order by his.id, start_date;

    其中第一部分是吧2019-02-14所有新增和变化(全量表)的数据插入临时表,
    第二部分是原历史表和新增变化表左连接,如果新增变化变存在id,则end_date置为前一天。
    如果没有匹配到,代表没有变化,end_date保持不变,即依旧是9999-99-99,说明该条数据是有效的。
    同时记得条件要有end_date = ‘9999-99-99’,表示只与当前最新的订单状态进行匹配。
    将拉链表数据用临时表覆盖
    因为hive修改字段值不方便,直接全变覆盖
    insert overwrite table dwd_order_info_his
    insert into table
    select * from dwd_order_info_his_tmp;