数仓(一)简介数仓,OLTP和OLAP

数仓(二)关系建模和维度建模

数仓(三)简析阿里、美团、网易、恒丰银行、马蜂窝5家数仓分层架构

数仓(四)数据仓库分层

数仓 (五) 元数据管理系统解析

数仓(六)从0到1简单搭建数仓ODS层(埋点日志 + 业务数据)

数仓(七)从0到1简单搭建加载数仓DIM层以及拉链表处理

数仓(八)从0到1简单搭建加载数仓DWD层(用户行为日志数据解析)

上一次我们讲解了DWD层(关于用户交易等业务数据)的搭建、解析加载。这节我们讲解DWS层关于各个主题的加工和使用,这层是宽表聚合值,是各个事实表的聚合值。

一、DWS层概念回顾

在第四章我们对DWS层做了概述,现在我们再来回顾一下。

DWS(Data Warehouse Service)

  • 使轻度汇总层,从ODS层中对用户的行为做一个初步的汇总,抽象出来一些通用的维度:时间、ip、id,并根据这些维度做一些统计值。

  • 这里做轻度的汇总会让以后的计算更加的高效,如:统计各个主题对象计算7天、30天、90天的行为, 应对特殊需求(例如,购买行为,统计商品复购率)会快很多不必走ODS层反复拿数据做加工。

  • 这层以分析的主题对象作为建模驱动,基于上层的应用和产品的指标需求,构建公共粒度的汇总指标事实表,以宽表化手段物理化模型。构建命名规范、口径一致的统计指标,为上层提供公共指标,建立汇总宽表、明细事实表。

  • 服务于 DWT 层的主题宽表,以及一些业务明细数据。

涉及的主题包括:访客主题、用户主题、商品主题、优惠券主题、活动主题、地区主题等。

二、DWS层用户主题加工

用户主题记录某一个用户在某一天的汇总行为。

1、首先我们看一下我们需要统计或者说加工的指标,一共是25个左右;

login_count` BIGINT COMMENT '登录次数',
`cart_count` BIGINT COMMENT '加入购物车次数',
`favor_count` BIGINT COMMENT '收藏次数',
`order_count` BIGINT COMMENT '下单次数',
`order_activity_count` BIGINT COMMENT '订单参与活动次数',
`order_activity_reduce_amount` DECIMAL(16,2) COMMENT '订单减免金额(活动)',
`order_coupon_count` BIGINT COMMENT '订单用券次数',
`order_coupon_reduce_amount` DECIMAL(16,2) COMMENT '订单减免金额(使用优惠券)',
`order_original_amount` DECIMAL(16,2)  COMMENT '订单单原始金额',
`order_final_amount` DECIMAL(16,2) COMMENT '订单总金额',
`payment_count` BIGINT COMMENT '支付次数',
`payment_amount` DECIMAL(16,2) COMMENT '支付金额',
`refund_order_count` BIGINT COMMENT '退单次数',
`refund_order_num` BIGINT COMMENT '退单件数',
`refund_order_amount` DECIMAL(16,2) COMMENT '退单金额',
`refund_payment_count` BIGINT COMMENT '退款次数',
`refund_payment_num` BIGINT COMMENT '退款件数',
`refund_payment_amount` DECIMAL(16,2) COMMENT '退款金额',
`coupon_get_count` BIGINT COMMENT '优惠券领取次数',
`coupon_using_count` BIGINT COMMENT '优惠券使用(下单)次数',
`coupon_used_count` BIGINT COMMENT '优惠券使用(支付)次数',
`appraise_good_count` BIGINT COMMENT '好评数',
`appraise_mid_count` BIGINT COMMENT '中评数',
`appraise_bad_count` BIGINT COMMENT '差评数',
`appraise_default_count` BIGINT COMMENT '默认评价数',
`order_detail_stats` array<struct<sku_id:string,sku_num:bigint,order_count:bigint,activity_reduce_amount:decimal(16,2),coupon_reduce_amount:decimal(16,2),original_amount:decimal(16,2),final_amount:decimal(16,2)>> COMMENT '下单明细统计'

2、根据指标建表

这里我们搭建DWS层级表,XXXX就是上面指标的字段。

DROP TABLE IF EXISTS dws_user_action_daycount;
CREATE EXTERNAL TABLE dws_user_action_daycount
(    XXXXX    ......
)
COMMENT '每日用户行为'PARTITIONED BY (`dt` STRING)
STORED AS PARQUETLOCATION
'/warehouse/gmall/dws/dws_user_action_daycount/'
TBLPROPERTIES ("parquet.compression"="lzo");

3、逐个计算指标

3.1 login_count 登录次数

这个指标简单,根据dwd层,dwd_page_log表可以直接计算;

select    dt,    user_id,   count(*) login_count
from dwd_page_log
where user_id is not null
and last_page_id is null
group by dt,user_id

3.2 cart_count 加入购物车次数;

      favor_count 收藏次数;

这两个指标也是很简单,直接根据dwd层,dwd_action_log表中获取

SQL实现

select    dt,    user_id,    sum(if(action_id='cart_add',1,0)) cart_count,sum(if(action_id='favor_add',1,0)) favor_count
from dwd_action_log
where user_id is not null
and action_id in ('cart_add','favor_add')
group by dt,user_id

3.3 order_count 下单次数;

order_activity_count 订单参与活动次数;

order_activity_reduce_amount 订单减免金额(活动);

order_coupon_count 订单用券次数;

order_coupon_reduce_amount 订单减免金额(使用优惠券);

order_original_amount  订单单原始金额;

order_final_amount  订单总金额;

订单表的几个指标相对也很简单,直接根据dwd层,dwd_order_info表中获取

SQL实现

select    date_format(create_time,'yyyy-MM-dd') dt,   user_id,    count(*) order_count,    sum(if(activity_reduce_amount>0,1,0)) order_activity_count,    sum(if(coupon_reduce_amount>0,1,0)) order_coupon_count,    sum(activity_reduce_amount) order_activity_reduce_amount,    sum(coupon_reduce_amount) order_coupon_reduce_amount,    sum(original_amount) order_original_amount,    sum(final_amount) order_final_amount
from dwd_order_info
group by date_format(create_time,'yyyy-MM-dd'),user_id

3.4 payment_count'支付次数',

      payment_amount'支付金额',

SQL实现

selectdate_format(callback_time,'yyyy-MM-dd') dt,user_id,count(*) payment_count,sum(payment_amount) payment_amount
from dwd_payment_info
group by date_format(callback_time,'yyyy-MM-dd'),user_id

3.5 refund_order_count 退单次数',

refund_order_num 退单件数',

refund_order_amount '退单金额',

SQL实现

selectdate_format(create_time,'yyyy-MM-dd') dt,user_id,count(*) refund_order_count,sum(refund_num) refund_order_num,sum(refund_amount) refund_order_amount
from dwd_order_refund_info
group by date_format(create_time,'yyyy-MM-dd'),user_id

3.6refund_payment_count '退款次数',

refund_payment_num '退款件数',

refund_payment_amount '退款金额',

ri表示上述退单中间表,rp表示退款中间表;然后做左外链接取交集;

SQL实现

selectdate_format(callback_time,'yyyy-MM-dd') dt,rp.user_id,count(*) refund_payment_count,sum(ri.refund_num) refund_payment_num,sum(rp.refund_amount) refund_payment_amountfrom(selectuser_id,order_id,sku_id,refund_amount,callback_timefrom dwd_refund_payment)rpleft join(selectuser_id,order_id,sku_id,refund_numfrom dwd_order_refund_info)rion rp.order_id=ri.order_idand rp.sku_id=rp.sku_idgroup by date_format(callback_time,'yyyy-MM-dd'),rp.user_id

3.7coupon_get_count '优惠券领取次数',

coupon_using_count '优惠券使用(下单)次数',

coupon_used_count '优惠券使用(支付)次数',

SQL实现

selectcoalesce(coupon_get.dt,coupon_using.dt,coupon_used.dt) dt,coalesce(coupon_get.user_id,coupon_using.user_id,coupon_used.user_id) user_id,nvl(coupon_get_count,0) coupon_get_count,nvl(coupon_using_count,0) coupon_using_count,nvl(coupon_used_count,0) coupon_used_count
from
(selectdate_format(get_time,'yyyy-MM-dd') dt,user_id,count(*) coupon_get_countfrom dwd_coupon_usewhere get_time is not nullgroup by user_id,date_format(get_time,'yyyy-MM-dd')
)coupon_get
full outer join
(selectdate_format(using_time,'yyyy-MM-dd') dt,user_id,count(*) coupon_using_countfrom dwd_coupon_usewhere using_time is not nullgroup by user_id,date_format(using_time,'yyyy-MM-dd')
)coupon_using
on coupon_get.dt=coupon_using.dt
and coupon_get.user_id=coupon_using.user_id
full outer join
(selectdate_format(used_time,'yyyy-MM-dd') dt,user_id,count(*) coupon_used_countfrom dwd_coupon_usewhere used_time is not nullgroup by user_id,date_format(used_time,'yyyy-MM-dd')
)coupon_used
on nvl(coupon_get.dt,coupon_using.dt)=coupon_used.dt
and nvl(coupon_get.user_id,coupon_using.user_id)=coupon_used.user_id
)

3.8appraise_good_count '好评数',

appraise_mid_count  '中评数',

appraise_bad_count  '差评数',

这个数值直接从dwd层,dwd_comment_info表里面取sum值

SQL实现

selectdate_format(create_time,'yyyy-MM-dd') dt,user_idsum(if(appraise='1201',1,0)) appraise_good_count,sum(if(appraise='1202',1,0)) appraise_mid_count,sum(if(appraise='1203',1,0)) appraise_bad_count,sum(if(appraise='1204',1,0)) appraise_default_count
from dwd_comment_info
group by date_format(create_time,'yyyy-MM-dd'),user_id

4、完成首日和每日加载

汇总SQL后做首日装载,分区是动态分区dt

insert overwrite table dws_user_action_daycount partition(dt)
selectcoalesce(tmp_login.user_id,tmp_cf.user_id,tmp_order.user_id,tmp_pay.user_id,tmp_ri.user_id,tmp_rp.user_id,tmp_comment.user_id,tmp_coupon.user_id,tmp_od.user_id),nvl(login_count,0),nvl(cart_count,0),nvl(favor_count,0),XXXX,

每日装载,dt = 当前时间分区;

insert overwrite table dws_user_action_daycount partition(dt='2020-06-15')
selectcoalesce(tmp_login.user_id,tmp_cf.user_id,tmp_order.user_id,tmp_pay.user_id,tmp_ri.user_id,tmp_rp.user_id,tmp_comment.user_id,tmp_coupon.user_id,tmp_od.user_id),nvl(login_count,0),nvl(cart_count,0),nvl(favor_count,0),nvl(order_count,0),

这样我们就完成了关于用户主题的DWS层的汇聚值的计算。

请读者参考后完成以下主题:

访客主题、商品主题、优惠券主题、活动主题、地区主题等,每日装载和首装载的SQL。


总结:

  1. 数仓DWS层的概念、作用;

  2. DWS层的宽表聚合值是各个事实表的聚合值,怎么样加工和计算?

数仓(十)从0到1简单搭建加载数仓DWS层相关推荐

  1. 十分钟用Windows服务器简单搭建DHCP中继代理!!

                         十分钟用Windows服务器简单搭建DHCP中继代理!! 一.什么是中继代理? 大家都知道DHCP分配地址都需要用到IP广播,但是广播是不能在两个网段之间进行 ...

  2. “存储区更新、插入或删除语句影响到以外的行数(0)。实体在加载后可能被修改或删除”如何解决

    做项目的时候,我们的try... catch语句捕捉到这种异常,我们该如何解决呢? 之所以出现这样的异常,是因为我们用实体对象在接收页面的参数时,并没有接收到实体对象的主键,所以我们要在视图那里获取到 ...

  3. html canvas直线进度条,js+HTML5 canvas 实现简单的加载条(进度条)功能示例

    本文实例讲述了js+HTML5 canvas 实现简单的加载条(进度条)功能.分享给大家供大家参考,具体如下: www.jb51.net canvas实现加载条动画 /* * 获取canvas, ca ...

  4. 最简单的加载器免杀思路

    本文首发于先知社区:https://xz.aliyun.com/t/9385 这部分源代码开放:https://github.com/MrWQ/HanGuang 最简单的加载器免杀思路 将加载器的变量 ...

  5. 基于iSroll 5.0实现的上拉加载和下拉刷新插件

    Updownload.js 基于iSroll 5.0实现的上拉加载和下拉刷新插件 移动端效果比较好,开发者工具打开后,需要刷新下页面. [演示地址:] https://chenyk2016.githu ...

  6. 数仓(六)从0到1简单搭建数仓ODS层(埋点日志 + 业务数据)

    数仓(一)简介数仓,OLTP和OLAP 数仓(二)关系建模和维度建模 数仓(三)简析阿里.美团.网易.恒丰银行.马蜂窝5家数仓分层架构 数仓(四)数据仓库分层 数仓(五)元数据管理系统解析 最近工作一 ...

  7. 十四、猜码游戏: 每一轮里,程序随机生成两个数字,一个是码数,范围:0到5,一个是猜数,范围:码数到10。用户输入两个数字,也分为码数和猜数。 若这一轮程序的猜数等于两个码数之和,输出“电脑胜”,若

    import random a=int(input('请输入码数')) b=int(input('请输入猜数')) i=random.randint(0,6) j=random.randint(i,1 ...

  8. 数仓实战|两步搞定Hive数据加载到Greenplum

    如果说Hive是离线数仓的代表,那么Greenplum就是MPP数据库的代表.在离线数仓的年代,以Hive为核心的数据仓库席卷数据仓库市场,几乎成为了离线数仓的代名词.但是Hive的查询能力非常弱,通 ...

  9. Android OpenGLES2.0(十四)——Obj格式3D模型加载

    转自:http://blog.csdn.net/junzia/article/details/54300202 在博主<OpenGLES系列>文章中,最开始的几篇讲的就是OpenGL世界中 ...

最新文章

  1. 算法与数据结构(Java解八皇后问题)
  2. 计算机怎么模拟人,计算机能不能模拟人的思维?
  3. __VA_ARGS__宏
  4. java wordcount程序_WordCount程序(java)
  5. PHP从零开始--字段修饰符数据操作SQL语言
  6. LOJ#2145. 「SHOI2017」分手是祝愿
  7. 盘点提高程序员技术的5个免费编程网站,你知道几个?
  8. USACO-Section1.3 Name That Number (遍历与字符串比较)
  9. java路由方法_Linux添加路由的方法
  10. eslint常规语法检
  11. 天线发射功率计算公式_天线基本知识及应用―链路及空间无线传播损耗计算
  12. python在线编辑器手机-‎App Store 上的quot;Python AI - 代码编辑器”
  13. Vue学习之路---No.5(分享心得,欢迎批评指正)
  14. 搜索和内容生态的关系
  15. 用VBS脚本实现软件定条件开启
  16. Idempotent Consumer
  17. javascript网页设计期末作业 购物网站
  18. 2020.4.11普及C组 Loan Repayment【纪中】【二分】
  19. 计算机二级系统班C语言讲义,计算机二级C语言2017辅导讲义:C语言基本知识
  20. 开源世界里的重要理念:上游优先(UpStream First)

热门文章

  1. 基于java的消防系统
  2. 合理的网页设计具有哪些特征
  3. 【云原生进阶之容器】第一章Docker核心技术1.6节——UnionFS
  4. 【历史上的今天】1 月 15 日:维基百科上线;信息安全大师出生;英特尔推出 Viiv
  5. Ubuntu 14.04 更换源(官方源——阿里源)
  6. 工控随笔_10_西门子_WinCC的VBS脚本_01_基础入门
  7. Android Dialer模块联系人搜索
  8. android模拟器 出错:X Error of failed request: BadRequest (invalid request code or no such operation)
  9. Python 小小爬虫练手,爬取自己的IP
  10. 【医学影像】几个医学影像专业一定要知道的网站