数仓之订单详情事实表【价格分摊】

数仓之订单详情事实表【价格分摊】

1.创建订单详情事实表

drop table if exists dwd_fact_order_detail;
create external table dwd_fact_order_detail (
                                                `id` string COMMENT '订单编号',
                                                `order_id` string COMMENT '订单号',
                                                `user_id` string COMMENT '用户id',
                                                `sku_id` string COMMENT 'sku商品id',
                                                `sku_name` string COMMENT '商品名称',
                                                `order_price` decimal(16,2) COMMENT '商品价格',
                                                `sku_num` bigint COMMENT '商品数量',
                                                `create_time` string COMMENT '创建时间',
                                                `province_id` string COMMENT '省份ID',
                                                `source_type` string COMMENT '来源类型',
                                                `source_id` string COMMENT '来源编号',
                                                `original_amount_d` decimal(20,2) COMMENT '原始价格分摊',
                                                `final_amount_d` decimal(20,2) COMMENT '购买价格分摊',
                                                `feight_fee_d` decimal(20,2) COMMENT '分摊运费',
                                                `benefit_reduce_amount_d` decimal(20,2) COMMENT '分摊优惠'
) COMMENT '订单明细事实表表'
    PARTITIONED BY (`dt` string)--按天进行分区
    stored as parquet--列式存储parquet
    location '/warehouse/gmall/dwd/dwd_fact_order_detail/'--HDFS数据的位置
    tblproperties ("parquet.compression"="lzo");--采用LZO对数据压缩

2.编写脚本

#!/bin/bash

#指定数据库&hive路径
APP=gmall
hive=/opt/module/hive-3.1.2/bin/hive

#如果是输入的日期按照取输入日期;如果没输入日期取当前时间的前一天
if [ -n "$2" ] ;then
    do_date=$2
else 
    do_date=`date -d "-1 day" +%F`
fi

sql1="
set mapreduce.job.queuename=hive;
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;

#订单详情表
insert overwrite table ${APP}.dwd_fact_order_detail partition(dt='$do_date')
select
    id,
    order_id,
    user_id,
    sku_id,
    sku_num,
    order_price,
    sku_num,
    create_time,
    province_id,
    source_type,
    source_id,
    original_amount_d,--原始价格分摊=商品价格*商品数量
    if(rn=1,final_total_amount-(sum_div_final_amount-final_amount_d),final_amount_d),--购买价格分摊
    if(rn=1,feight_fee-(sum_div_feight_fee-feight_fee_d),feight_fee_d),--分摊运费
    if(rn=1,benefit_reduce_amount-(sum_div_benefit_reduce_amount-benefit_reduce_amount_d),benefit_reduce_amount_d)--分摊优惠
from
(
    select
        od.id,
        od.order_id,
        od.user_id,
        od.sku_id,
        od.sku_name,
        od.order_price,
        od.sku_num,
        od.create_time,
        oi.province_id,
        od.source_type,
        od.source_id,
        round(od.order_price*od.sku_num,2) original_amount_d, --原始价格分摊 = 商品价格*商品数量
        round(od.order_price*od.sku_num/oi.original_total_amount*oi.final_total_amount,2) final_amount_d,--购买价格分摊 = (商品价格*商品数量/原价金额)*订单金额
        round(od.order_price*od.sku_num/oi.original_total_amount*oi.feight_fee,2) feight_fee_d,--运费分摊 = (商品价格*商品数量/原价金额)*订单运费
        round(od.order_price*od.sku_num/oi.original_total_amount*oi.benefit_reduce_amount,2) benefit_reduce_amount_d,--优惠分摊=(商品价格*商品数量/原价金额)*订单优惠金额
        row_number() over(partition by od.order_id order by od.id desc) rn,
        oi.final_total_amount,--订单金额
        oi.feight_fee,--订单运费
        oi.benefit_reduce_amount,--订单优惠金额
        sum(round(od.order_price*od.sku_num/oi.original_total_amount*oi.final_total_amount,2)) over(partition by od.order_id) sum_div_final_amount,--购买价格的总和
        sum(round(od.order_price*od.sku_num/oi.original_total_amount*oi.feight_fee,2)) over(partition by od.order_id) sum_div_feight_fee,--分摊运费的总和
        sum(round(od.order_price*od.sku_num/oi.original_total_amount*oi.benefit_reduce_amount,2)) over(partition by od.order_id) sum_div_benefit_reduce_amount--分摊优惠的总和
    from 
    (
        select * from ${APP}.ods_order_detail where dt='$do_date'
    ) od
    join 
    (
        select * from ${APP}.ods_order_info where dt='$do_date'
    ) oi
    on od.order_id=oi.id
)t1";

#sql的运行
 $hive -e "$sql"

3.思路

1.查询 ods层的[订单表+订单详情表]进行关联
2.计算[原始价格分摊,购买价格分摊,运费分摊,优惠分摊]
3.计算[购买价格运费的总和,分摊运费的总和,分摊优惠的总和]
4.考虑特殊情况:分摊有余
取商品开窗的第一条数据:[订单总额-购买价格的总和+第一条的购买价格分摊]

if(rn=1,final_total_amount-(sum_div_final_amount-final_amount_d),final_amount_d)

5.重新写入覆盖到dwd层订单详情表

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值