Featured image of post 电商用户行为分析

电商用户行为分析

本文简要介绍了电商用户行为分析离线数仓的搭建及效果展示。

一、项目介绍

  • 项目概述

    本项目旨在构建一个完整的电商用户行为离线数据仓库系统,用于存储、处理和分析电商平台的用户行为数据及业务数据,为企业的经营分析、用户画像、推荐系统等提供数据支持。

  • 项目进度

    • 已完成数据采集架构搭建和HDFS存储设计
    • 正在进行数据仓库分层建模和ETL流程开发
    • 后续将完善数据质量监控和可视化展示
  • 项目价值

    • 用户行为分析:分析用户路径、转化漏斗、停留时长等,优化用户体验
    • 精准营销:基于用户画像实现个性化推荐和精准营销
    • 经营分析:监控核心业务指标(KPI),辅助经营决策
    • 库存优化:分析商品销售趋势,优化库存管理
  • 项目效果

    warehouse_screen

二、项目规划

  • 集群规划

    四台虚拟机(centos7)、Termius(虚拟机连接)

    服务名称 子服务 服务器 hadoop102 服务器 hadoop103 服务器 hadoop104
    HDFS NameNode
    DataNode
    SecondaryNameNode
    Yarn NodeManager
    Resourcemanager
    Zookeeper Zookeeper Server
    Flume(采集日志) Flume
    Kafka Kafka
    Flume(消费Kafka日志) Flume
    Flume(消费Kafka业务) Flume
    Hive
    MySQL MySQL
    DataX
    Spark
    DolphinScheduler ApiApplicationServer
    AlertServer
    MasterServer
    WorkerServer
    LoggerServer
    Superset Superset
    Flink
    ClickHouse
    Redis
    Hbase
  • 项目流程

    data_warehouse_flow

  • 项目架构

    • 数据采集层(cluster.sh

      用户行为日志采集:

      • 使用Flume构建日志收集系统,实时采集用户在前端的点击、浏览、搜索、加购、下单等行为日志
      • 日志数据以JSON格式存储到HDFS分布式文件系统
      • 自定义拦截器进行数据初步过滤、格式化以及零点漂移问题

      业务数据同步:

      • 使用Maxwell监控MySQL binlog,实时捕获业务数据库的变更
      • 使用Maxwell-bootstrap实现历史全量数据同步
      • 使用DataX进行批量数据同步,处理全量历史数据
      • 自定义拦截器解决零点漂移问题
      • 业务数据包括用户信息、商品信息、订单数据、支付数据等
    • 数据存储层

      • 采用HDFS作为底层分布式存储系统
      • 使用Hive构建数据仓库,实现结构化数据存储
      • 分区表设计按日期分区,优化查询性能
    • 数据处理层

      • 使用Hive SQL进行ETL处理,通过DataGrip实现
      • 实现数据清洗、转换、聚合等操作
      • 采用DolphinScheduler进行任务调度
    • 数据服务层

      • 使用DataX将分析结果导出到关系型数据库供业务系统使用
      • 通过Superset工具实现数据可视化

三、数仓开发

  • ER建模 or 维度建模

    data_warehouse_model

  • 维度建模

    • 事实表:用户行为事件、订单事实、支付事实等
    • 维度表:用户维度、商品维度、时间维度、地区维度等
  • 分层设计

    1. ODS层(原始数据层)
      • ODS层的表结构设计依托于业务系统同步过来的数据结构
      • ODS层要保存全部历史数据,故其压缩格式应选择压缩比较高的,此处选择gzip
      • ODS层表名的命名规范为:ods_表名_单分区增量/全量标识(inc / full)
    2. DIM层(维度层)
      • DIM层的设计依据是维度建模理论,该层存储维度模型的维度表
      • DIM层的数据存储格式为orc列式存储+snappy压缩
      • DIM层表名的命名规范为dim_表名_全量表或者拉链表标识(full / zip)
    3. DWD层(明细数据层)
      • DWD层的设计依据是维度建模理论,该层存储维度模型的事实表
      • DWD层的数据存储格式为orc列式存储+snappy压缩
      • DWD层表名的命名规范为dwd_数据域_表名_单分区增量/全量标识(inc / full)
    4. DWS层(汇总数据层)
      • DWS层的设计参考指标体系

      • DWS层的数据存储格式为orc列式存储+snappy压缩

      • DWS层表名的命名规范为dws_数据域_统计粒度_业务过程_统计周期(1d/nd/td)

        1d表示最近1日,nd表示最近n日,td表示历史至今

    5. ADS层(应用数据层)
      • 面向具体业务场景的高度聚合数据
      • 包含用户留存分析、转化漏斗、商品销量排行等主题

四、设计细节

  • ODS层

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    
    -- ODS层
        -- Operate Data Store
            -- 存储从mysql业务数据库和日志服务器的日志文件中采集到的数据
                -- 日志数据
                    -- 格式:JSON
                -- 业务数据
                    -- 历史数据
                    -- 格式:
                        -- 全量
                            -- DataX:TSV
                        -- 增量
                            -- Maxwell:JSON
            -- 汇总数据
                -- 希望用最少的资源存最多的数据
                    -- 压缩:gzip
                        -- gzip:Hadoop默认支持的,压缩效率不高,压缩率极高
                        -- lzo:Hadoop默认不支持的,压缩效率一般,压缩率高
                        -- snappy:Hadoop默认不支持的,压缩效率极高,压缩率不高
                    -- 数据格式尽可能不变
                    -- 压缩格式尽可能不变
            -- 命名规范
                -- 在数据仓库中,表其实都是放置在一起的。从逻辑上进行区分,进行分层
                -- 表从名称上区分每一层
                -- 分层标记(ods_) + 同步数据的表名称 + 全量/增量标识(full/inc)
    
    -- 日志表
        -- 表的数据就是同步过来的日志数据
            -- 页面浏览日志:JSON
            -- APP启动日志:JSON
        -- ods_log_inc
            -- 字段
        -- 建表语句
            -- EXTERNAL
                -- 外部表
            -- LOCATION
                -- 位置
        -- 日志数据格式:
            -- 页面浏览日志
                -- JSON中含有JSON
                    -- JSON表中的JSON数据如果存在嵌套的情况
                        -- 一般会将最外层的JSON对象的属性作为JSON表的字段
                    -- common
                    -- actions
                    -- displays
                    -- page
                    -- err
                    -- ts
                -- 表的字段类型应该采用特殊类型
            -- APP启动日志
                -- JSON中含有JSON
                    -- common
                    -- start
                    -- err
                    -- ts
    
    -- DROP TABLE IF EXISTS ods_log_inc;
    -- CREATE EXTERNAL TABLE ods_log_inc
    -- (
    --     -- common:struct<ar:string, br:string ...>
    --     -- actions:array<struct<action_id:string, item:string ...>>
    --     -- displays:array<struct<action_id:string, item:string ...>>
    --     -- page:struct
    --     -- err:struct
    --     -- ts:bigint
    --     -- start:struct
    -- ) COMMENT '活动信息表'
    -- PARTITIONED BY (`dt` STRING)
    -- ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.JsonSerDe'
    -- LOCATION '/warehouse/gmall/ods/ods_log_inc/';
    
    DROP TABLE IF EXISTS ods_log_inc;
    CREATE EXTERNAL TABLE ods_log_inc
    (
        `common` STRUCT<ar :STRING,
            ba :STRING,
            ch :STRING,
            is_new :STRING,
            md :STRING,
            mid :STRING,
            os :STRING,
            sid :STRING,
            uid :STRING,
            vc :STRING> COMMENT '公共信息',
        `page` STRUCT<during_time :STRING,
            item :STRING,
            item_type :STRING,
            last_page_id :STRING,
            page_id :STRING,
            from_pos_id :STRING,
            from_pos_seq :STRING,
            refer_id :STRING> COMMENT '页面信息',
        `actions` ARRAY<STRUCT<action_id:STRING,
            item:STRING,
            item_type:STRING,
            ts:BIGINT>> COMMENT '动作信息',
        `displays` ARRAY<STRUCT<display_type :STRING,
            item :STRING,
            item_type :STRING,
            `pos_seq` :STRING,
            pos_id :STRING>> COMMENT '曝光信息',
        `start` STRUCT<entry :STRING,
            first_open :BIGINT,
            loading_time :BIGINT,
            open_ad_id :BIGINT,
            open_ad_ms :BIGINT,
            open_ad_skip_ms :BIGINT> COMMENT '启动信息',
        `err` STRUCT<error_code:BIGINT,
                msg:STRING> COMMENT '错误信息',
        `ts` BIGINT  COMMENT '时间戳'
    ) COMMENT '活动信息表'
        PARTITIONED BY (`dt` STRING)
        ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.JsonSerDe'
    LOCATION '/warehouse/gmall/ods/ods_log_inc/'
    TBLPROPERTIES ('compression.codec'='org.apache.hadoop.io.compress.GzipCodec');
    
    -- 装载数据
        -- load:HDFS
        -- save:ods_log_inc
    -- hive:file -> load -> table
    
    -- load data:剪切
    load data inpath '/origin_data/gmall/log/topic_log/2022-06-08' into table 
    ods_log_inc partition(dt='2022-06-08');
    
    -- 分区表
        -- hive中的表一般都包含分区
        -- hive中表的数据通常非常多,底层采用很多数据文件进行保存
            -- 查询时,会从数据文件中按照条件进行查询
                -- 一旦数据多、文件大、文件多,都会影响查询效率
            -- 通过建立分区的操作,让查询效率提高
                -- 将数据文件不是放置在一起,而是根据某些条件存储到不同的路径下
                    -- 这里的条件就是分区
            -- 分区表,存在分区字段,这个字段不是数据字段,而是用于文件目录的划分,不会存储到数据文件中
                -- dt:date
    DROP TABLE IF EXISTS test_part;
    CREATE TABLE test_part
    (
        id int
    ) COMMENT '活动信息表'
    PARTITIONED BY (`dt` STRING)
    LOCATION '/test/test_part';
    
    insert into table test_part values (1, '2022-06-08'); -- 真实的数据字段 虚拟的分区字段
    -- 静态分区:分区字段的值为固定值
    insert into table test_part partition (dt = '2022-06-08') values (1);
    -- 动态分区:分区字段取自于查询结果
        -- 分区字段不能赋值
        -- 查询字段应该在最后增加一个额外的字段用于分区操作,所以称之为分区字段
        -- 默认情况下 Hive 没有开启动态分区的处理
    set hive.exec.dynamic.partition.mode=nonstrict;
    insert into table test_part partition (dt)
    select 2, '2022-06-09';
    
    set hive.mapred.mode=nonstrict;
    select
        *
    from test_part
    where dt = "2022-06-09";
    --------------------------------------------------------
    -- log:JSON
        -- 默认情况下,Hive的表无法解析JSON格式
        -- 如果 Hive 表可以解析JSON格式的数据,那么一般称之为JSON表
            -- 如果JSON属性和表的字段相同,那么可以正常解析
            -- 如果JSON属性少于表的字段,那么存在的属性可以正常解析,不存在的字段会被设定为null
            -- 如果JSON属性多于表的字段,那么多余属性不做解析
            -- 如果JSON属性和表的字段大小写有差异,会进行不区分大小写的解析
    DROP TABLE IF EXISTS test_log;
    CREATE TABLE test_log
    (
        id bigint,
        name string,
        age bigint
    ) COMMENT '活动信息表'
    ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.JsonSerDe'
    LOCATION '/test/test_log/';
    
    -- map, array, struct
        -- array
            -- 使用 [] 表示数组,访问时就是采用中括号加索引的方式进行访问
            -- 如果索引超出范围,并不会发生错误,而是直接返回null
    DROP TABLE IF EXISTS test_datatype;
    CREATE TABLE test_datatype
    (
        ids array<int>,
        dat map<string, string>,
        obj struct<id:int, name:string>
    ) COMMENT '活动信息表'
    LOCATION '/test/test_datatype/';
    /*
     子查询 (select array(1, 2, 3, 4) as ids) t
     创建了一个临时表 t,其中包含一列 ids,值为数组 [1, 2, 3, 4]
     外层查询 从临时表 t 中选择 ids 列作为结果
     */
    select
        ids,
        ids[5],
        array( ids[1], ids[2] ),
        array_contains(ids, 5)
    from
    (select `array`(1, 2, 3, 4) ids )
    t where array_contains(ids, 8)
    ;
    
    -- map
        -- 显示效果类似于JSON对象
            -- map数据的访问,不能直接通过key来操作
            -- 访问数据时,采用类似于数组的方式,但是不是采用索引,而是key
            -- 如果key不存在,那么直接返回null
    select
        dat,
        dat[0],
        dat['a'],
        map_keys(dat),
        map_values(dat),
        if (array_contains(map_keys(dat), 'c'), 3, 4)
    from
        (select `map`('a', 'b', 'c', 1) dat ) -- <'a', 'b'> <'c', 1>
    t;
    
    -- struct:对象
        -- 显示效果类似于JSON对象
            -- struct:会将所有数据作为属性值存在
            -- 访问对象中存在的属性时,不能采用中括号,直接采用点的方式就可以
            -- 访问对象中不存在的属性时,会直接发生错误
    
    select struct('a', 'b', 'c', 'd');
    
    -- map和struct区别
        -- 泛型
        -- struct中的属性名称是固定的,只要约束好不能发生变化
        -- map中的key不是固定的,可以动态判断
    select
        obj,
        obj.a,
        obj.e
    from (select named_struct('a', 'b', 'c', 1) obj) t;
    
    -- 业务表
        -- 全量表:DataX 表结构和业务表保持一致即可
            -- TSV
                -- mysql:column[id, name, age]
                -- data:1001    zhangsan    30
                -- hive:column[id, name, age]
        -- 增量表:Maxwell
            -- JSON
                -- 最外层JSON对象的属性作为表的字段
    
    DROP TABLE IF EXISTS ods_activity_info_full;
    CREATE EXTERNAL TABLE ods_activity_info_full
    (
        `id`              STRING COMMENT '活动id',
        `activity_name` STRING COMMENT '活动名称',
        `activity_type` STRING COMMENT '活动类型',
        `activity_desc` STRING COMMENT '活动描述',
        `start_time`     STRING COMMENT '开始时间',
        `end_time`        STRING COMMENT '结束时间',
        `create_time`    STRING COMMENT '创建时间',
        `operate_time`   STRING COMMENT '修改时间'
    ) COMMENT '活动信息表'
        PARTITIONED BY (`dt` STRING)
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        NULL DEFINED AS ''
    LOCATION '/warehouse/gmall/ods/ods_activity_info_full/'
    TBLPROPERTIES ('compression.codec'='org.apache.hadoop.io.compress.GzipCodec');
    
    DROP TABLE IF EXISTS ods_activity_rule_full;
    CREATE EXTERNAL TABLE ods_activity_rule_full
    (
        `id`                  STRING COMMENT '编号',
        `activity_id`       STRING COMMENT '活动ID',
        `activity_type`     STRING COMMENT '活动类型',
        `condition_amount` DECIMAL(16, 2) COMMENT '满减金额',
        `condition_num`     BIGINT COMMENT '满减件数',
        `benefit_amount`    DECIMAL(16, 2) COMMENT '优惠金额',
        `benefit_discount` DECIMAL(16, 2) COMMENT '优惠折扣',
        `benefit_level`     STRING COMMENT '优惠级别',
        `create_time`       STRING COMMENT '创建时间',
        `operate_time`      STRING COMMENT '修改时间'
    ) COMMENT '活动规则表'
        PARTITIONED BY (`dt` STRING)
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        NULL DEFINED AS ''
    LOCATION '/warehouse/gmall/ods/ods_activity_rule_full/'
    TBLPROPERTIES ('compression.codec'='org.apache.hadoop.io.compress.GzipCodec');
    
    
    DROP TABLE IF EXISTS ods_cart_info_inc;
    CREATE EXTERNAL TABLE ods_cart_info_inc
    (
        `type` STRING COMMENT '变动类型',
        `ts`   BIGINT COMMENT '变动时间',
        `data` STRUCT<id :STRING,
            user_id :STRING,
            sku_id :STRING,
            cart_price :DECIMAL(16, 2),
            sku_num :BIGINT,
            img_url :STRING,
            sku_name :STRING,
            is_checked :STRING,
            create_time :STRING,
            operate_time :STRING,
            is_ordered :STRING,
            order_time:STRING> COMMENT '数据',
        `old`  MAP<STRING,STRING> COMMENT '旧值' -- old中不确定字段的个数(修改字段)
    ) COMMENT '购物车增量表'
        PARTITIONED BY (`dt` STRING)
        ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.JsonSerDe'
    LOCATION '/warehouse/gmall/ods/ods_cart_info_inc/'
    TBLPROPERTIES ('compression.codec'='org.apache.hadoop.io.compress.GzipCodec');
    
    DROP TABLE IF EXISTS test_loc;
    CREATE TABLE test_loc
    (
        id int
    ) COMMENT '活动信息表'
    LOCATION '/test/test_loc';
    
  • DIM层

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
    665
    666
    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    680
    681
    682
    683
    684
    685
    686
    687
    688
    689
    690
    691
    692
    693
    694
    695
    696
    697
    698
    699
    700
    701
    702
    703
    704
    705
    706
    707
    708
    709
    710
    711
    712
    713
    714
    715
    716
    717
    718
    719
    720
    721
    722
    723
    724
    725
    726
    727
    728
    729
    730
    731
    732
    733
    734
    735
    736
    737
    738
    739
    740
    741
    742
    743
    744
    745
    746
    747
    748
    749
    750
    751
    752
    753
    754
    755
    756
    757
    758
    759
    760
    761
    762
    763
    764
    765
    766
    767
    768
    769
    770
    771
    772
    773
    774
    775
    776
    777
    778
    779
    780
    781
    782
    783
    784
    785
    786
    787
    788
    789
    790
    791
    792
    793
    794
    795
    796
    797
    798
    799
    800
    801
    802
    803
    804
    805
    806
    807
    808
    809
    810
    811
    812
    813
    814
    815
    816
    817
    818
    819
    820
    
    -- DIM层
        -- Dimension:维度
            -- 所谓的维度其实就是分析数据的角度表
                -- 性别
                -- 年龄
                -- 品牌
                -- 品类
            -- 维度层保存维度表,所以建模理论应该遵循维度建模理论
                -- 维度层中的维度表主要用于统计分析
                    -- 数据存储方式应该为列式存储:orc(行式存储不利于统计分析)
                    -- 数据压缩效率越高越好(时间短):snappy
                -- 数据源
                    -- ODS层的数据为整个数据仓库做准备
                    -- DIM层数据源就是ODS层
            --命名规范
                -- 分层标记 (dim_)_维度名称_全量/拉链(标识)
                    -- 全量:维度表的全部数据
                        -- 状态数据为了避免数据出现问题,最好的方式就是每一天都保存全部数据
                    -- 绝大多数的维度表都是全量表,特殊情况采用拉链的方式
    
        -- 建模理论
            -- ER模型
                -- ODS
            -- 维度模型
                -- 维度(状态)表
                -- 事实(行为)表
        -- 维度表
            -- 表
                -- 维度(角度),一个维度就是一张表
                    -- t_order, t_sex, t_age
                -- 从实践来讲,一般会将有关联性的维度设置为一张表,不同的维度就是这张表的字段
                    -- t_order, t_user(sex, age)
                    -- t_order, t_tm, t_category -> t_order, t_sku(tm, category)
                -- 如果维度特别简单,特别独立,只在特殊场合用,可不创建,在事实表中直接使用,无需单独创建
                    -- t_payment_type:微信支付、支付宝支付、银联支付
            -- 字段
                -- 维度:只要能用来进行分析的维度,都是字段(有些表的字段,如密码、头像无需分析,不能成为字段)
            -- 数据(字段)来源:参考业务数据库的表字段
                -- 主维表:业务数据库中主要用于分析维度字段的表
                -- 相关维表:业务数据库中相关用于分析维度字段的表
    
                -- 维度字段的确定
                    -- 尽可能生成丰富的维度属性:字段越多越好
                    -- 字段越多不会影响统计分析(列式存储),需要哪列取哪列,不用即不需要取
                    -- 编码和文字共存
                    -- 沉淀出(计算)通用的维度属性
                        -- 时间 2023-02-01
                        -- tel
    
    -- 商品维度表
        -- dim_sku_full
            -- 全量维度表:以天为单位将数据全部同步到维度表的相同时间分区中
            -- 业务数据库的表
                -- 主维表:sku_info
                -- 相关维表:
                -- sku_attr_value
                -- sku_sale_attr_value
    
    -- 建表语句
    DROP TABLE IF EXISTS dim_sku_full;
    CREATE EXTERNAL TABLE dim_sku_full
    (
        `id`                   STRING COMMENT 'SKU_ID',
        `price`                DECIMAL(16, 2) COMMENT '商品价格',
        `sku_name`             STRING COMMENT '商品名称',
        `sku_desc`             STRING COMMENT '商品描述',
        `weight`               DECIMAL(16, 2) COMMENT '重量',
        `is_sale`              BOOLEAN COMMENT '是否在售',
        `spu_id`               STRING COMMENT 'SPU编号',
        `spu_name`             STRING COMMENT 'SPU名称',
        `category3_id`         STRING COMMENT '三级品类ID',
        `category3_name`       STRING COMMENT '三级品类名称',
        `category2_id`         STRING COMMENT '二级品类id',
        `category2_name`       STRING COMMENT '二级品类名称',
        `category1_id`         STRING COMMENT '一级品类ID',
        `category1_name`       STRING COMMENT '一级品类名称',
        `tm_id`                  STRING COMMENT '品牌ID',
        `tm_name`               STRING COMMENT '品牌名称',
        `sku_attr_values`      ARRAY<STRUCT<attr_id :STRING,
            value_id :STRING,
            attr_name :STRING,
            value_name:STRING>> COMMENT '平台属性',
        `sku_sale_attr_values` ARRAY<STRUCT<sale_attr_id :STRING,
            sale_attr_value_id :STRING,
            sale_attr_name :STRING,
            sale_attr_value_name:STRING>> COMMENT '销售属性',
        `create_time`          STRING COMMENT '创建时间'
    ) COMMENT '商品维度表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dim/dim_sku_full/'
        TBLPROPERTIES ('orc.compress' = 'snappy');  -- 默认gzip
    
    
    -- 装载数据
        -- load
            -- 补全数据
                -- 补全行:union
                -- 补全列:join
                    -- join, left join, right join, full join
        -- save
            -- 以时间为单位(分区)进行保存
            -- 采集汇总哪一天的数据,就保存到哪一天的分区中
            -- insert into:插入
            -- insert overwrite:覆盖
            -- 大数据中没有事务的概念,如果执行到中间失败,下面不会再执行,需要retry整个脚本,使用insert into会导致已成功执行的重复
    insert overwrite table dim_sku_full partition (dt='2022-06-08')
    select
         sku.`id`                  ,--STRING COMMENT 'SKU_ID',
        `price`                ,--DECIMAL(16, 2) COMMENT '商品价格',
        `sku_name`             ,--STRING COMMENT '商品名称',
        `sku_desc`             ,--STRING COMMENT '商品描述',
        `weight`               ,--DECIMAL(16, 2) COMMENT '重量',
        `is_sale`              ,--BOOLEAN COMMENT '是否在售',
        `spu_id`               ,--STRING COMMENT 'SPU编号',
        `spu_name`             ,--STRING COMMENT 'SPU名称',
        `category3_id`         ,--STRING COMMENT '三级品类ID',
        `category3_name`       ,--STRING COMMENT '三级品类名称',
        `category2_id`         ,--STRING COMMENT '二级品类id',
        `category2_name`       ,--STRING COMMENT '二级品类名称',
        `category1_id`         ,--STRING COMMENT '一级品类ID',
        `category1_name`       ,--STRING COMMENT '一级品类名称',
        `tm_id`                ,--  STRING COMMENT '品牌ID',
        `tm_name`              ,-- STRING COMMENT '品牌名称',
        `sku_attr_values`      ,
        `sku_sale_attr_values` ,
        `create_time`           --STRING COMMENT '创建时间'
    from (
        select
            `id`                   ,--STRING COMMENT 'SKU_ID',
            `price`                ,--DECIMAL(16, 2) COMMENT '商品价格',
            `sku_name`             ,--STRING COMMENT '商品名称',
            `sku_desc`             ,--STRING COMMENT '商品描述',
            `weight`               ,--DECIMAL(16, 2) COMMENT '重量',
            `is_sale`              ,--BOOLEAN COMMENT '是否在售',
            `spu_id`               ,--STRING COMMENT 'SPU编号',
            --`spu_name`             ,--STRING COMMENT 'SPU名称',
            `category3_id`         ,--STRING COMMENT '三级品类ID',
            --`category3_name`       ,--STRING COMMENT '三级品类名称',
            --`category2_id`         ,--STRING COMMENT '二级品类id',
            --`category2_name`       ,--STRING COMMENT '二级品类名称',
            --`category1_id`         ,--STRING COMMENT '一级品类ID',
            --`category1_name`       ,--STRING COMMENT '一级品类名称',
            `tm_id`                ,--STRING COMMENT '品牌ID',
            --`tm_name`              ,--STRING COMMENT '品牌名称',
            `create_time`           --STRING COMMENT '创建时间'
        from ods_sku_info_full
        where dt = '2022-06-08'
    ) sku
    left join (
        select
            id,
            spu_name
        from ods_spu_info_full
        where dt = '2022-06-08'
    ) spu on sku.spu_id = spu.id
    left join (
        select
            id,
            tm_name
        from ods_base_trademark_full
        where dt = '2022-06-08'
    ) tm on sku.tm_id = tm.id
    left join (
        select
            id,
            name category3_name,
            category2_id
        from ods_base_category3_full
        where dt = '2022-06-08'
    ) c3 on sku.category3_id = c3.id
    left join (
        select
            id,
            name category2_name,
            category1_id
        from ods_base_category2_full
        where dt = '2022-06-08'
    ) c2 on c3.category2_id = c2.id
    left join (
        select
            id,
            name category1_name
        from ods_base_category1_full
        where dt = '2022-06-08'
    ) c1 on c2.category1_id = c1.id
    left join (
        select
            sku_id,
            collect_list(named_struct("attr_id", attr_id, "value_id", value_id, "attr_name", attr_name, "value_name", value_name)) sku_attr_values
        from ods_sku_attr_value_full
        where dt = '2022-06-08'
        group by sku_id
    ) sav on sav.sku_id = sku.id
    left join (
        select
            sku_id,
            collect_list(named_struct("sale_attr_id", sale_attr_id, "sale_attr_value_id", sale_attr_value_id, "sale_attr_name", sale_attr_name, "sale_attr_value_name", sale_attr_value_name)) sku_sale_attr_values
        from ods_sku_sale_attr_value_full
        where dt = '2022-06-08'
        group by sku_id
    ) ssav on ssav.sku_id = sku.id;
    
    -- 1. struct
    -- 2. 相同的sku n * struct -> array
        -- 聚合函数 -> array
    select
        sku_id,
        collect_list(named_struct("attr_id", attr_id, "value_id", value_id, "attr_name", attr_name, "value_name", value_name))
    from ods_sku_attr_value_full
    where dt = '2022-06-08'
    group by sku_id;
    
    -- CTE
    select
        *
    from (
        select *
        from (
            select
                *
            from ods_user_info_inc
            where dt = '2022-06-08'
        ) t1
    ) t
    join (
        select
            *
        from (
            select *
            from ods_user_info_inc
            where dt = '2022-06-08'
        ) t1
    ) t2;
    
    with t as (select * from ods_user_info_inc where dt = '2022-06-08')
    select
        *
    from (
        select
            *
        from t
    ) t1
    join (
        select
            *
        from t
    ) t2;
    
    
    -- 优惠券维度表
        -- 主维表:coupon_info
        -- 相关维表
            -- coupon_range(冗余)
            -- coupon_use(行为)
    DROP TABLE IF EXISTS dim_coupon_full;
    CREATE EXTERNAL TABLE dim_coupon_full
    (
        `id`                  STRING COMMENT '优惠券编号',
        `coupon_name`       STRING COMMENT '优惠券名称',
        `coupon_type_code` STRING COMMENT '优惠券类型编码', -- 编码与名称共存
        `coupon_type_name` STRING COMMENT '优惠券类型名称',
        `condition_amount` DECIMAL(16, 2) COMMENT '满额数',
        `condition_num`     BIGINT COMMENT '满件数',
        `activity_id`       STRING COMMENT '活动编号',
        `benefit_amount`   DECIMAL(16, 2) COMMENT '减免金额',
        `benefit_discount` DECIMAL(16, 2) COMMENT '折扣',
        `benefit_rule`     STRING COMMENT '优惠规则:满元*减*元,满*件打*折', -- 沉淀,通过计算得到
        `create_time`       STRING COMMENT '创建时间',
        `range_type_code`  STRING COMMENT '优惠范围类型编码',
        `range_type_name`  STRING COMMENT '优惠范围类型名称',
        `limit_num`         BIGINT COMMENT '最多领取次数',
        `taken_count`       BIGINT COMMENT '已领取次数',
        `start_time`        STRING COMMENT '可以领取的开始时间',
        `end_time`          STRING COMMENT '可以领取的结束时间',
        `operate_time`      STRING COMMENT '修改时间',
        `expire_time`       STRING COMMENT '过期时间'
    ) COMMENT '优惠券维度表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dim/dim_coupon_full/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    
    -- 数据装载
        -- load
            -- coupon_info
            -- base_dic
        -- save
    insert overwrite table dim_coupon_full partition (dt='2022-06-08')
    select
        `id`                  ,--STRING COMMENT '优惠券编号',
        `coupon_name`         ,--STRING COMMENT '优惠券名称',
        `coupon_type_code`    ,--STRING COMMENT '优惠券类型编码', -- 编码与名称共存
        `coupon_type_name`    ,--STRING COMMENT '优惠券类型名称',
        `condition_amount`    ,--DECIMAL(16, 2) COMMENT '满额数',
        `condition_num`       ,--BIGINT COMMENT '满件数',
        `activity_id`         ,--STRING COMMENT '活动编号',
        `benefit_amount`      ,--DECIMAL(16, 2) COMMENT '减免金额',
        `benefit_discount`    ,--DECIMAL(16, 2) COMMENT '折扣',
        `benefit_rule`        ,--STRING COMMENT '优惠规则:满元*减*元,满*件打*折', -- 沉淀,通过计算得到
        `create_time`         ,--STRING COMMENT '创建时间',
        `range_type_code`     ,--STRING COMMENT '优惠范围类型编码',
        `range_type_name`     ,--STRING COMMENT '优惠范围类型名称',
        `limit_num`           ,--BIGINT COMMENT '最多领取次数',
        `taken_count`         ,--BIGINT COMMENT '已领取次数',
        `start_time`          ,--STRING COMMENT '可以领取的开始时间',
        `end_time`            ,--STRING COMMENT '可以领取的结束时间',
        `operate_time`        ,--STRING COMMENT '修改时间',
        `expire_time`         --STRING COMMENT '过期时间'
    from (
        select
            `id`                  ,--STRING COMMENT '优惠券编号',
            `coupon_name`         ,--STRING COMMENT '优惠券名称',
            coupon_type `coupon_type_code`    ,--STRING COMMENT '优惠券类型编码', -- 编码与名称共存
            --`coupon_type_name`    ,--STRING COMMENT '优惠券类型名称',
            `condition_amount`    ,--DECIMAL(16, 2) COMMENT '满额数',
            `condition_num`       ,--BIGINT COMMENT '满件数',
            `activity_id`         ,--STRING COMMENT '活动编号',
            `benefit_amount`      ,--DECIMAL(16, 2) COMMENT '减免金额',
            `benefit_discount`    ,--DECIMAL(16, 2) COMMENT '折扣',
            case coupon_type
                when '3201' then concat('满', condition_amount, '元减', benefit_amount, '元')
                when '3202' then concat('满', condition_num, '件打', benefit_discount, '折')
                when '3203' then concat('减', benefit_amount, '元')
            end `benefit_rule`        ,--STRING COMMENT '优惠规则:满元*减*元,满*件打*折', -- 沉淀,通过计算得到
            `create_time`         ,--STRING COMMENT '创建时间',
            range_type `range_type_code`     ,--STRING COMMENT '优惠范围类型编码',
            --`range_type_name`     ,--STRING COMMENT '优惠范围类型名称',
            `limit_num`           ,--BIGINT COMMENT '最多领取次数',
            `taken_count`         ,--BIGINT COMMENT '已领取次数',
            `start_time`          ,--STRING COMMENT '可以领取的开始时间',
            `end_time`            ,--STRING COMMENT '可以领取的结束时间',
            `operate_time`        ,--STRING COMMENT '修改时间',
            `expire_time`         --STRING COMMENT '过期时间'
        from ods_coupon_info_full
        where dt = '2022-06-08'
    ) cp
    join (
        select
            dic_code,
            dic_name coupon_type_name
        from ods_base_dic_full
        where dt = '2022-06-08'
        and parent_code= '32'
    ) dic1 on dic1.dic_code = cp.coupon_type_code
    join (
        select
            dic_code,
            dic_name range_type_name
        from ods_base_dic_full
        where dt = '2022-06-08'
        and parent_code= '33'
    ) dic2 on dic2.dic_code = cp.range_type_code;
    
    -- 活动维度表
        -- activity_info:相关维表
        -- activity_rule:主维表
        -- activity_sku (x)
    
    DROP TABLE IF EXISTS dim_activity_full;
    CREATE EXTERNAL TABLE dim_activity_full
    (
        `activity_rule_id`   STRING COMMENT '活动规则ID',
        `activity_id`         STRING COMMENT '活动ID',
        `activity_name`       STRING COMMENT '活动名称',
        `activity_type_code` STRING COMMENT '活动类型编码',
        `activity_type_name` STRING COMMENT '活动类型名称',
        `activity_desc`       STRING COMMENT '活动描述',
        `start_time`           STRING COMMENT '开始时间',
        `end_time`             STRING COMMENT '结束时间',
        `create_time`          STRING COMMENT '创建时间',
        `condition_amount`    DECIMAL(16, 2) COMMENT '满减金额',
        `condition_num`       BIGINT COMMENT '满减件数',
        `benefit_amount`      DECIMAL(16, 2) COMMENT '优惠金额',
        `benefit_discount`   DECIMAL(16, 2) COMMENT '优惠折扣',
        `benefit_rule`        STRING COMMENT '优惠规则',
        `benefit_level`       STRING COMMENT '优惠级别'
    ) COMMENT '活动维度表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dim/dim_activity_full/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- 数据装载
    insert overwrite table dim_activity_full partition (dt='2022-06-08')
    select
        `activity_rule_id`   ,--STRING COMMENT '活动规则ID',
        `activity_id`        ,-- STRING COMMENT '活动ID',
        `activity_name`      ,-- STRING COMMENT '活动名称',
        `activity_type_code` ,--STRING COMMENT '活动类型编码',
        `activity_type_name` ,--STRING COMMENT '活动类型名称',
        `activity_desc`      ,-- STRING COMMENT '活动描述',
        `start_time`         ,--  STRING COMMENT '开始时间',
        `end_time`           ,--  STRING COMMENT '结束时间',
        `create_time`        ,--  STRING COMMENT '创建时间',
        `condition_amount`   ,-- DECIMAL(16, 2) COMMENT '满减金额',
        `condition_num`      ,-- BIGINT COMMENT '满减件数',
        `benefit_amount`     ,-- DECIMAL(16, 2) COMMENT '优惠金额',
        `benefit_discount`   ,--DECIMAL(16, 2) COMMENT '优惠折扣',
        `benefit_rule`       ,-- STRING COMMENT '优惠规则',
        `benefit_level`      -- STRING COMMENT '优惠级别'
    from (
        select
            `id` `activity_rule_id`, -- STRING COMMENT '活动规则ID',
            `activity_id`        ,-- STRING COMMENT '活动ID',
            --`activity_name`      ,-- STRING COMMENT '活动名称',
            activity_type `activity_type_code` ,-- STRING COMMENT '活动类型编码',
            --`activity_type_name` ,-- STRING COMMENT '活动类型名称',
            `create_time`        ,-- STRING COMMENT '创建时间',
            `condition_amount`   ,-- DECIMAL(16, 2) COMMENT '满减金额',
            `condition_num`      ,-- BIGINT COMMENT '满减件数',
            `benefit_amount`     ,-- DECIMAL(16, 2) COMMENT '优惠金额',
            `benefit_discount`   ,-- DECIMAL(16, 2) COMMENT '优惠折扣',
            case activity_type
                when '3101' then concat('满', condition_amount, '元减', benefit_amount, '元')
                when '3102' then concat('满', condition_num, '件打', benefit_discount, '折')
                when '3103' then concat('打', benefit_discount, '折')
            end `benefit_rule`  ,-- STRING COMMENT '优惠规则',
            `benefit_level`      -- STRING COMMENT '优惠级别'
        from ods_activity_rule_full
        where dt = '2022-06-08'
    ) rule
    left join (
        select
            id,
            activity_name,
            `activity_desc`      ,-- STRING COMMENT '活动描述',
            `start_time`         ,-- STRING COMMENT '开始时间',
            `end_time`            -- STRING COMMENT '结束时间',
        from ods_activity_info_full
        where dt = '2022-06-08'
    
    ) info on rule.activity_id = info.id
    left join (
        select
            dic_code,
            dic_name activity_type_name
        from ods_base_dic_full
        where dt = '2022-06-08'
        and parent_code = '31'
    ) dic on rule.activity_type_code = dic.dic_code;
    
    -- 地区维度表
        -- 建表语句
    DROP TABLE IF EXISTS dim_province_full;
    CREATE EXTERNAL TABLE dim_province_full
    (
        `id`              STRING COMMENT '省份ID',
        `province_name` STRING COMMENT '省份名称',
        `area_code`     STRING COMMENT '地区编码',
        `iso_code`      STRING COMMENT '旧版国际标准地区编码,供可视化使用',
        `iso_3166_2`    STRING COMMENT '新版国际标准地区编码,供可视化使用',
        `region_id`     STRING COMMENT '地区ID',
        `region_name`   STRING COMMENT '地区名称'
    ) COMMENT '地区维度表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dim/dim_province_full/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- 数据装载
    insert overwrite table dim_province_full partition (dt='2022-06-08')
    select
        prv.`id`              ,--STRING COMMENT '省份ID',
        `province_name`       ,--STRING COMMENT '省份名称',
        `area_code`           ,--STRING COMMENT '地区编码',
        `iso_code`            ,--STRING COMMENT '旧版国际标准地区编码,供可视化使用',
        `iso_3166_2`          ,--STRING COMMENT '新版国际标准地区编码,供可视化使用',
        `region_id`           ,--STRING COMMENT '地区ID',
        `region_name`         --STRING COMMENT '地区名称'
    from (
        select
            `id`              ,--STRING COMMENT '省份ID',
            name `province_name`   ,--STRING COMMENT '省份名称',
            `area_code`       ,--STRING COMMENT '地区编码',
            `iso_code`        ,--STRING COMMENT '旧版国际标准地区编码,供可视化使用',
            `iso_3166_2`      ,--STRING COMMENT '新版国际标准地区编码,供可视化使用',
            `region_id`       --STRING COMMENT '地区ID',
            --`region_name`     --STRING COMMENT '地区名称'
        from ods_base_province_full
        where dt = '2022-06-08'
    ) prv
    left join (
        select
            id,
            region_name
        from ods_base_region_full
        where dt = '2022-06-08'
    ) region on prv.region_id = region.id;
    
    -- 营销坑位表
        -- 建表语句
    DROP TABLE IF EXISTS dim_promotion_pos_full;
    CREATE EXTERNAL TABLE dim_promotion_pos_full
    (
        `id`                 STRING COMMENT '营销坑位ID',
        `pos_location`       STRING COMMENT '营销坑位位置',
        `pos_type`           STRING COMMENT '营销坑位类型 ',
        `promotion_type`     STRING COMMENT '营销类型',
        `create_time`        STRING COMMENT '创建时间',
        `operate_time`       STRING COMMENT '修改时间'
    ) COMMENT '营销坑位维度表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dim/dim_promotion_pos_full/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    insert overwrite table dim_promotion_pos_full partition (dt='2022-06-08')
    select
        `id`                ,--STRING COMMENT '营销坑位ID',
        `pos_location`      ,--STRING COMMENT '营销坑位位置',
        `pos_type`          ,--STRING COMMENT '营销坑位类型 ',
        `promotion_type`    ,--STRING COMMENT '营销类型',
        `create_time`       ,--STRING COMMENT '创建时间',
        `operate_time`       --STRING COMMENT '修改时间'
    from ods_promotion_pos_full
    where dt = '2022-06-08';
    
    -- 营销渠道维度表
        -- 建表语句
    DROP TABLE IF EXISTS dim_promotion_refer_full;
    CREATE EXTERNAL TABLE dim_promotion_refer_full
    (
        `id`                  STRING COMMENT '营销渠道ID',
        `refer_name`          STRING COMMENT '营销渠道名称',
        `create_time`         STRING COMMENT '创建时间',
        `operate_time`        STRING COMMENT '修改时间'
    ) COMMENT '营销渠道维度表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dim/dim_promotion_refer_full/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    insert overwrite table dim_promotion_refer_full partition (dt='2022-06-08')
    select
        `id`                  ,--STRING COMMENT '营销渠道ID',
        `refer_name`          ,--STRING COMMENT '营销渠道名称',
        `create_time`         ,--STRING COMMENT '创建时间',
        `operate_time`         --STRING COMMENT '修改时间'
    from ods_promotion_refer_full
    where dt = '2022-06-08';
    
    -- 日期维度表
        -- 建表语句
    DROP TABLE IF EXISTS dim_date;
    CREATE EXTERNAL TABLE dim_date
    (
        `date_id`    STRING COMMENT '日期ID',
        `week_id`    STRING COMMENT '周ID,一年中的第几周',
        `week_day`   STRING COMMENT '周几',
        `day`         STRING COMMENT '每月的第几天',
        `month`       STRING COMMENT '一年中的第几月',
        `quarter`    STRING COMMENT '一年中的第几季度',
        `year`        STRING COMMENT '年份',
        `is_workday` STRING COMMENT '是否是工作日',
        `holiday_id` STRING COMMENT '节假日'
    ) COMMENT '日期维度表'
        STORED AS ORC
        LOCATION '/warehouse/gmall/dim/dim_date/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- 数据装载
        -- 创建临时表
    DROP TABLE IF EXISTS tmp_dim_date_info;
    CREATE EXTERNAL TABLE tmp_dim_date_info (
        `date_id`       STRING COMMENT '日',
        `week_id`       STRING COMMENT '周ID',
        `week_day`      STRING COMMENT '周几',
        `day`            STRING COMMENT '每月的第几天',
        `month`          STRING COMMENT '第几月',
        `quarter`       STRING COMMENT '第几季度',
        `year`           STRING COMMENT '年',
        `is_workday`    STRING COMMENT '是否是工作日',
        `holiday_id`    STRING COMMENT '节假日'
    ) COMMENT '时间维度表'
    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' -- tsv
    LOCATION '/warehouse/gmall/tmp/tmp_dim_date_info/';
    
    -- tsv(行式) -> orc(列式)
    -- Hive -> SQL -> Spark
    insert into table dim_date select * from tmp_dim_date_info; -- 自动转换格式
    
    -- 用户维度表(用增量的方式来表示全量)
        -- user_info
        -- user_address
        -- 建表语句
    DROP TABLE IF EXISTS dim_user_zip;
    CREATE EXTERNAL TABLE dim_user_zip
    (
        `id`           STRING COMMENT '用户ID',
        `name`         STRING COMMENT '用户姓名',
        `phone_num`    STRING COMMENT '手机号码',
        `email`        STRING COMMENT '邮箱',
        `user_level`   STRING COMMENT '用户等级',
        `birthday`     STRING COMMENT '生日',
        `gender`       STRING COMMENT '性别',
        `create_time`  STRING COMMENT '创建时间',
        `operate_time` STRING COMMENT '操作时间',
        `start_date`   STRING COMMENT '开始日期',  -- 类似于聚合
        `end_date`     STRING COMMENT '结束日期'
    ) COMMENT '用户维度表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dim/dim_user_zip/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    insert overwrite table dim_user_zip partition (dt='2022-06-08')
    select
        *
    from ods_user_info_inc
    where dt = '2022-06-08';
    
    -- 数据的基数
        -- 每日全量数据
            -- 每天同步一份全部的数据
                -- 40 * 400 * 5 = 80000(行) * 1kb = 80Mb
                -- 40w * 400 * 5 = 800Gb
            -- 用户
                -- 2000w * 400 * 5 = 40Tb
        -- 将数据状态的变化记录下来,而不是全部数据,而是指定时间范围 (start, end)
            -- 在表的设计中,需要增加两个额外的字段,用于标识时间范围 (start, end)
            -- 表设计为拉链表(zip)即可
            -- 一般情况下,拉链表中截止到今天依然有效的状态的结束时间,为了不修改,所以设置为时间极大值 9999-12-31
    
    -- 拉链表的数据源应该是ods层增量表
        -- 增量表
            -- maxwell
                -- 数据格式:json
                -- 同步方式:
                    -- 首日:bootstrap(select)
                    -- 每日:insert, update, delete(binlog)
    -- 首日:全量
        -- 2022-06-08:数仓上线首日:user_info_all
            -- 首日获取的全量数据只有用户的最新状态数据,不存在历史数据,所以无法判断状态的开始
                -- 所以折中地认为首日就是当前最新状态的开始日期
                -- 将最新状态的结束时间设为时间极大值
        -- 拉链表的分区策略
            -- 将数据存储到哪一个分区,更方便我们的查询
                -- 假设将用户数据保存到用户的开始日期的分区中
                    -- zhangsan 2022-06-08 9999-12-31 => 2022-06-08
                    -- lisi     2022-06-08 2022-06-08 => 2022-06-08
                    -- lisi     2022-06-09 9999-12-31 => 2022-06-09
                    -- select * from t_user where dt = '2022-06-08';
                -- 假设将用户数据保存到用户的结束日期的分区中
                    -- zhangsan 2022-06-08 9999-12-31 => 9999-12-31
                    -- lisi     2022-06-08 2022-06-08 => 2022-06-08
                    -- lisi     2022-06-09 9999-12-31 => 9999-12-31
                    -- select * from t_user where dt = '2022-06-08';
            -- 将数据存储到结束时间所在分区
    insert overwrite table dim_user_zip partition (dt='9999-12-31')
    select
        type,
        data.`id`           ,--STRING COMMENT '用户ID',
        data.`name`         ,--STRING COMMENT '用户姓名',
        data.`phone_num`    ,--STRING COMMENT '手机号码',
        data.`email`        ,--STRING COMMENT '邮箱',
        data.`user_level`   ,--STRING COMMENT '用户等级',
        data.`birthday`     ,--STRING COMMENT '生日',
        data.`gender`       ,--STRING COMMENT '性别',
        data.`create_time`  ,--STRING COMMENT '创建时间',
        data.`operate_time` ,--STRING COMMENT '操作时间',
        '2022-06-08'   ,--STRING COMMENT '开始日期',
        '9999-12-31'     --STRING COMMENT '结束日期'
    from ods_user_info_inc
    where dt = '2022-06-08'
    and type = 'bootstrap-insert';
    
    -- 每日:增量
        -- 增加的用户信息
            -- type:insert
            -- start:当天(2022-06-09)
            -- end:9999-12-31
            -- partition:9999-12-31
        -- 修改的用户信息
            -- 修改后
                -- type:update
                -- start:当天(2022-06-09)
                -- end:9999-12-31
                -- partition:9999-12-31
            -- 修改前
                -- dim_user_zip (dt=9999-12-31)
                -- start:start
                -- end:9999-12-31 -> 2022-06-08
                -- partition:9999-12-31 -> 2022-06-08
    
    -- 修改
    -- insert overwrite table  xxx
    -- select
    --     '2022-06-08' dt
    -- from (
    --     select '9999-12-31' dt
    -- ) t
    
    -- 每日数据装载
        -- union:去重
        -- union all:不去重
    set hive.exec.dynamic.partition.mode=nonstrict;
    insert overwrite table dim_user_zip partition (dt) -- 动态分区
    select
        `id`           ,--STRING COMMENT '用户ID',
        `name`         ,--STRING COMMENT '用户姓名',
        `phone_num`    ,--STRING COMMENT '手机号码',
        `email`        ,--STRING COMMENT '邮箱',
        `user_level`   ,--STRING COMMENT '用户等级',
        `birthday`     ,--STRING COMMENT '生日',
        `gender`       ,--STRING COMMENT '性别',
        `create_time`  ,--STRING COMMENT '创建时间',
        `operate_time` ,--STRING COMMENT '操作时间',
        `start_date`   ,--STRING COMMENT '开始日期',
        if ( rn == 2, date_sub('2022-06-09', 1), '9999-12-31'),
        if ( rn == 2, date_sub('2022-06-09', 1), '9999-12-31')
    from (
        select
            *,
            row_number() over ( partition by id order by start_date desc ) rn
        from (
            select
                `id`           ,--STRING COMMENT '用户ID',
                `name`         ,--STRING COMMENT '用户姓名',
                `phone_num`    ,--STRING COMMENT '手机号码',
                `email`        ,--STRING COMMENT '邮箱',
                `user_level`   ,--STRING COMMENT '用户等级',
                `birthday`     ,--STRING COMMENT '生日',
                `gender`       ,--STRING COMMENT '性别',
                `create_time`  ,--STRING COMMENT '创建时间',
                `operate_time` ,--STRING COMMENT '操作时间',
                `start_date`   ,--STRING COMMENT '开始日期',
                `end_date`      --STRING COMMENT '结束日期'
            from dim_user_zip
            where dt = '9999-12-31'
            union all
            select
                data.`id`           ,--STRING COMMENT '用户ID',
                data.`name`         ,--STRING COMMENT '用户姓名',
                data.`phone_num`    ,--STRING COMMENT '手机号码',
                data.`email`        ,--STRING COMMENT '邮箱',
                data.`user_level`   ,--STRING COMMENT '用户等级',
                data.`birthday`     ,--STRING COMMENT '生日',
                data.`gender`       ,--STRING COMMENT '性别',
                data.`create_time`  ,--STRING COMMENT '创建时间',
                data.`operate_time` ,--STRING COMMENT '操作时间',
                '2022-06-09'   ,--STRING COMMENT '开始日期',  -- 类似于聚合
                '9999-12-31'      --STRING COMMENT '结束日期'
            from ods_user_info_inc
            where dt = '2022-06-09'
            and type in ('insert', 'update')
        ) t
    ) t1;
    
    -- 比对方式
        -- 将数据集合并(union)在一起进行比对,需要查找数据的规律
        -- 将数据集连接(join)在一起进行比对
            -- full join + inner join
    
    set hive.exec.dynamic.partition.mode=nonstrict;
    insert overwrite table dim_user_zip partition (dt) -- 动态分区
    select
        `id`           ,--STRING COMMENT '用户ID',
        `name`         ,--STRING COMMENT '用户姓名',
        `phone_num`    ,--STRING COMMENT '手机号码',
        `email`        ,--STRING COMMENT '邮箱',
        `user_level`   ,--STRING COMMENT '用户等级',
        `birthday`     ,--STRING COMMENT '生日',
        `gender`       ,--STRING COMMENT '性别',
        `create_time`  ,--STRING COMMENT '创建时间',
        `operate_time` ,--STRING COMMENT '操作时间',
        `start_date`   ,--STRING COMMENT '开始日期',
        if ( rn == 2, date_sub('2022-06-09', 1), '9999-12-31'),
        if ( rn == 2, date_sub('2022-06-09', 1), '9999-12-31')
    from (
        select
            *,
            row_number() over ( partition by id order by start_date desc ) rn
        from (
            select
                `id`           ,--STRING COMMENT '用户ID',
                `name`         ,--STRING COMMENT '用户姓名',
                `phone_num`    ,--STRING COMMENT '手机号码',
                `email`        ,--STRING COMMENT '邮箱',
                `user_level`   ,--STRING COMMENT '用户等级',
                `birthday`     ,--STRING COMMENT '生日',
                `gender`       ,--STRING COMMENT '性别',
                `create_time`  ,--STRING COMMENT '创建时间',
                `operate_time` ,--STRING COMMENT '操作时间',
                `start_date`   ,--STRING COMMENT '开始日期',
                `end_date`      --STRING COMMENT '结束日期'
            from dim_user_zip
            where dt = '9999-12-31'
            union all
            select
                `id`           ,--STRING COMMENT '用户ID',
                `name`         ,--STRING COMMENT '用户姓名',
                `phone_num`    ,--STRING COMMENT '手机号码',
                `email`        ,--STRING COMMENT '邮箱',
                `user_level`   ,--STRING COMMENT '用户等级',
                `birthday`     ,--STRING COMMENT '生日',
                `gender`       ,--STRING COMMENT '性别',
                `create_time`  ,--STRING COMMENT '创建时间',
                `operate_time` ,--STRING COMMENT '操作时间',
                '2022-06-09'   ,--STRING COMMENT '开始日期',
                '9999-12-31'      --STRING COMMENT '结束日期'
            from (
                select
                    data.`id`           ,--STRING COMMENT '用户ID',
                    data.`name`         ,--STRING COMMENT '用户姓名',
                    data.`phone_num`    ,--STRING COMMENT '手机号码',
                    data.`email`        ,--STRING COMMENT '邮箱',
                    data.`user_level`   ,--STRING COMMENT '用户等级',
                    data.`birthday`     ,--STRING COMMENT '生日',
                    data.`gender`       ,--STRING COMMENT '性别',
                    data.`create_time`  ,--STRING COMMENT '创建时间',
                    data.`operate_time` ,--STRING COMMENT '操作时间',
                    row_number() over (partition by data.id order by ts desc) num
                from ods_user_info_inc
                where dt = '2022-06-09'
                and type in ('insert', 'update')
            ) a where num = 1
        ) t
    ) t1
    
  • DWD层

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
     100
     101
     102
     103
     104
     105
     106
     107
     108
     109
     110
     111
     112
     113
     114
     115
     116
     117
     118
     119
     120
     121
     122
     123
     124
     125
     126
     127
     128
     129
     130
     131
     132
     133
     134
     135
     136
     137
     138
     139
     140
     141
     142
     143
     144
     145
     146
     147
     148
     149
     150
     151
     152
     153
     154
     155
     156
     157
     158
     159
     160
     161
     162
     163
     164
     165
     166
     167
     168
     169
     170
     171
     172
     173
     174
     175
     176
     177
     178
     179
     180
     181
     182
     183
     184
     185
     186
     187
     188
     189
     190
     191
     192
     193
     194
     195
     196
     197
     198
     199
     200
     201
     202
     203
     204
     205
     206
     207
     208
     209
     210
     211
     212
     213
     214
     215
     216
     217
     218
     219
     220
     221
     222
     223
     224
     225
     226
     227
     228
     229
     230
     231
     232
     233
     234
     235
     236
     237
     238
     239
     240
     241
     242
     243
     244
     245
     246
     247
     248
     249
     250
     251
     252
     253
     254
     255
     256
     257
     258
     259
     260
     261
     262
     263
     264
     265
     266
     267
     268
     269
     270
     271
     272
     273
     274
     275
     276
     277
     278
     279
     280
     281
     282
     283
     284
     285
     286
     287
     288
     289
     290
     291
     292
     293
     294
     295
     296
     297
     298
     299
     300
     301
     302
     303
     304
     305
     306
     307
     308
     309
     310
     311
     312
     313
     314
     315
     316
     317
     318
     319
     320
     321
     322
     323
     324
     325
     326
     327
     328
     329
     330
     331
     332
     333
     334
     335
     336
     337
     338
     339
     340
     341
     342
     343
     344
     345
     346
     347
     348
     349
     350
     351
     352
     353
     354
     355
     356
     357
     358
     359
     360
     361
     362
     363
     364
     365
     366
     367
     368
     369
     370
     371
     372
     373
     374
     375
     376
     377
     378
     379
     380
     381
     382
     383
     384
     385
     386
     387
     388
     389
     390
     391
     392
     393
     394
     395
     396
     397
     398
     399
     400
     401
     402
     403
     404
     405
     406
     407
     408
     409
     410
     411
     412
     413
     414
     415
     416
     417
     418
     419
     420
     421
     422
     423
     424
     425
     426
     427
     428
     429
     430
     431
     432
     433
     434
     435
     436
     437
     438
     439
     440
     441
     442
     443
     444
     445
     446
     447
     448
     449
     450
     451
     452
     453
     454
     455
     456
     457
     458
     459
     460
     461
     462
     463
     464
     465
     466
     467
     468
     469
     470
     471
     472
     473
     474
     475
     476
     477
     478
     479
     480
     481
     482
     483
     484
     485
     486
     487
     488
     489
     490
     491
     492
     493
     494
     495
     496
     497
     498
     499
     500
     501
     502
     503
     504
     505
     506
     507
     508
     509
     510
     511
     512
     513
     514
     515
     516
     517
     518
     519
     520
     521
     522
     523
     524
     525
     526
     527
     528
     529
     530
     531
     532
     533
     534
     535
     536
     537
     538
     539
     540
     541
     542
     543
     544
     545
     546
     547
     548
     549
     550
     551
     552
     553
     554
     555
     556
     557
     558
     559
     560
     561
     562
     563
     564
     565
     566
     567
     568
     569
     570
     571
     572
     573
     574
     575
     576
     577
     578
     579
     580
     581
     582
     583
     584
     585
     586
     587
     588
     589
     590
     591
     592
     593
     594
     595
     596
     597
     598
     599
     600
     601
     602
     603
     604
     605
     606
     607
     608
     609
     610
     611
     612
     613
     614
     615
     616
     617
     618
     619
     620
     621
     622
     623
     624
     625
     626
     627
     628
     629
     630
     631
     632
     633
     634
     635
     636
     637
     638
     639
     640
     641
     642
     643
     644
     645
     646
     647
     648
     649
     650
     651
     652
     653
     654
     655
     656
     657
     658
     659
     660
     661
     662
     663
     664
     665
     666
     667
     668
     669
     670
     671
     672
     673
     674
     675
     676
     677
     678
     679
     680
     681
     682
     683
     684
     685
     686
     687
     688
     689
     690
     691
     692
     693
     694
     695
     696
     697
     698
     699
     700
     701
     702
     703
     704
     705
     706
     707
     708
     709
     710
     711
     712
     713
     714
     715
     716
     717
     718
     719
     720
     721
     722
     723
     724
     725
     726
     727
     728
     729
     730
     731
     732
     733
     734
     735
     736
     737
     738
     739
     740
     741
     742
     743
     744
     745
     746
     747
     748
     749
     750
     751
     752
     753
     754
     755
     756
     757
     758
     759
     760
     761
     762
     763
     764
     765
     766
     767
     768
     769
     770
     771
     772
     773
     774
     775
     776
     777
     778
     779
     780
     781
     782
     783
     784
     785
     786
     787
     788
     789
     790
     791
     792
     793
     794
     795
     796
     797
     798
     799
     800
     801
     802
     803
     804
     805
     806
     807
     808
     809
     810
     811
     812
     813
     814
     815
     816
     817
     818
     819
     820
     821
     822
     823
     824
     825
     826
     827
     828
     829
     830
     831
     832
     833
     834
     835
     836
     837
     838
     839
     840
     841
     842
     843
     844
     845
     846
     847
     848
     849
     850
     851
     852
     853
     854
     855
     856
     857
     858
     859
     860
     861
     862
     863
     864
     865
     866
     867
     868
     869
     870
     871
     872
     873
     874
     875
     876
     877
     878
     879
     880
     881
     882
     883
     884
     885
     886
     887
     888
     889
     890
     891
     892
     893
     894
     895
     896
     897
     898
     899
     900
     901
     902
     903
     904
     905
     906
     907
     908
     909
     910
     911
     912
     913
     914
     915
     916
     917
     918
     919
     920
     921
     922
     923
     924
     925
     926
     927
     928
     929
     930
     931
     932
     933
     934
     935
     936
     937
     938
     939
     940
     941
     942
     943
     944
     945
     946
     947
     948
     949
     950
     951
     952
     953
     954
     955
     956
     957
     958
     959
     960
     961
     962
     963
     964
     965
     966
     967
     968
     969
     970
     971
     972
     973
     974
     975
     976
     977
     978
     979
     980
     981
     982
     983
     984
     985
     986
     987
     988
     989
     990
     991
     992
     993
     994
     995
     996
     997
     998
     999
    1000
    1001
    1002
    1003
    1004
    1005
    1006
    1007
    1008
    1009
    1010
    1011
    1012
    1013
    1014
    1015
    1016
    1017
    1018
    1019
    1020
    1021
    1022
    1023
    1024
    1025
    1026
    1027
    1028
    1029
    1030
    1031
    1032
    1033
    1034
    1035
    1036
    1037
    1038
    1039
    1040
    1041
    1042
    1043
    1044
    1045
    1046
    1047
    1048
    1049
    1050
    1051
    1052
    1053
    1054
    1055
    1056
    1057
    1058
    1059
    1060
    1061
    1062
    1063
    1064
    1065
    1066
    1067
    1068
    1069
    1070
    1071
    1072
    1073
    1074
    1075
    1076
    1077
    1078
    1079
    1080
    1081
    1082
    1083
    1084
    1085
    1086
    1087
    1088
    1089
    1090
    1091
    1092
    1093
    1094
    1095
    1096
    1097
    1098
    1099
    1100
    1101
    1102
    1103
    1104
    1105
    1106
    1107
    1108
    1109
    1110
    1111
    1112
    1113
    1114
    1115
    1116
    1117
    1118
    1119
    1120
    1121
    1122
    1123
    1124
    1125
    1126
    1127
    1128
    1129
    1130
    1131
    1132
    1133
    1134
    1135
    1136
    
    -- DWD层
        -- Data Warehouse Detail
            -- detail:详细、明细
            -- 对ODS层的数据进行加工,为统计分析做准备
            -- DIM层主要功能其实是分析数据(面向状态)
            -- DWD层主要功能其实是统计分析(面向行为)
            -- DWD层的表中主要保存的就是业务行为数据,表的设计需要遵循建模理论 - 维度建模 - 事实(行为)表
            -- 数据存储格式:列式存储
            -- 数据压缩格式:snappy
            -- 业务过程其实指代的就是业务行为
        -- 命名规范
            -- 分层标记(dwd_) + 数据域(分类) + 原子行为(login_success) + 全量 / 增量
                -- 原则上来讲,所有的行为都应该是增量数据
                    -- 特殊情况下,会采用全量方式实现行为统计
        -- 事实表
            -- 包含维度
                -- 维度越多,行为越详细;维度越少,行为越简单
            -- 包含度量值
                -- 所有的行为必须可以用于统计,这里用于统计的值(字段)就是度量值
        -- 事实表分类
            -- 事务事实表
                -- 绝大多数的事实表都是事务型事实表
                    -- 事务:原子性
                    -- 原子操作(行为)
                        -- login success (table)
                        -- login fail (table)
                -- 粒度:行为描述的详细程度,称之为粒度
                    -- 描述的越详细,粒度越细,称之为细粒度
                        -- 维度越多,粒度越细
                    -- 描述的越简单,粒度越粗,称之为粗粒度
                        -- 维度越少,粒度越粗
                -- 建立表的时候,尽可能让粒度越细
                -- 创建表的步骤:
                    -- 选择业务过程:确定创建什么表
                    -- 声明粒度:确定行
                    -- 确认维度:确定列
                    -- 确认事实:确定度量值
            -- 周期快照事实表
            -- 累计快照事实表
    
    -- 交易域加购事务事实表
        -- 交易域
        -- 加购
            -- 购物车中没有这个商品,新增商品
            -- 购物车中有这个商品,增加购买商品的数量
        -- 事务事实表:至少将行为描述清楚
            -- 表:dwd_trade_add_cart_inc
            -- 行:用户 + 时间 + 商品 + 商品数量
            -- 列:user + date + sku + num
            -- 度量值:num + 次数
    
        -- 建表语句
    DROP TABLE IF EXISTS dwd_trade_cart_add_inc;
    CREATE EXTERNAL TABLE dwd_trade_cart_add_inc
    (
        `id`                  STRING COMMENT '编号',
        `user_id`            STRING COMMENT '用户ID',
        `sku_id`             STRING COMMENT 'SKU_ID',
        `date_id`            STRING COMMENT '日期ID',  -- yyyy-MM-dd 关联 dim_date
        `create_time`        STRING COMMENT '加购时间', -- yyyy-MM-dd hh:mm:ss
        `sku_num`            BIGINT COMMENT '加购物车件数'
    ) COMMENT '交易域加购事务事实表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dwd/dwd_trade_cart_add_inc/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- 数据装载
        -- load
            -- 获取加购行为的数据
                -- maxwell:增量数据(insert, update)
        -- save
    -- 从ods层的增量表中获取数据,能想到什么?
        -- 数据格式:JSON
        -- 首日:全量
            -- 历史数据(4、5、6、7、8)
            -- 无法判断行为
                -- 折中地认为当前的数据全部都是新增购物
        -- 每日:增量
            -- 当天新增及变化
        -- 分区策略
            -- 哪一天的行为数据就存放到哪一天的分区中
    insert overwrite table dwd_trade_cart_add_inc partition (dt)
    select
        data.`id`                 ,--STRING COMMENT '编号',
        data.`user_id`            ,--STRING COMMENT '用户ID',
        data.`sku_id`             ,--STRING COMMENT 'SKU_ID',
        date_format(data.`create_time`, 'yyyy-MM-dd') `date_id`            ,--STRING COMMENT '日期ID',  -- yyyy-MM-dd 关联 dim_date
        data.`create_time`        ,--STRING COMMENT '加购时间', -- yyyy-MM-dd HH:mm:ss
        data.`sku_num`            ,--BIGINT COMMENT '加购物车件数'
        date_format(data.`create_time`, 'yyyy-MM-dd')
    from ods_cart_info_inc
    where dt = '2022-06-08'
    and type = 'bootstrap-insert';
    
    -- 每日数据装载:不包含历史数据,主要当天新增及变化的数据
        -- 首日:2022-06-08
        -- 每日:2022-06-09,10,11 ……
        -- maxwell:{update, old : Map}
    insert overwrite table dwd_trade_cart_add_inc partition (dt='2022-06-09')
    select
        data.id,
        data.user_id,
        data.sku_id,
        date_format(if( type = 'insert', data.create_time, data.operate_time), 'yyyy-MM-dd'),
        if( type = 'insert', data.create_time, data.operate_time),
        if( type = 'insert', data.sku_num, data.sku_num - old['sku_num']) -- 自动转换
    from ods_cart_info_inc
    where dt = '2022-06-09'
    and (
        type = 'insert'
        or
        (
            type = 'update'
                and
            array_contains(map_keys(old), 'sku_num')
                and
            data.sku_num > cast(old['sku_num'] as bigint)
        )
    );
    
    -- long -> string(date) -> date_format(string, date)
    insert overwrite table dwd_trade_cart_add_inc partition (dt='2022-06-09')
    select
        data.id,
        data.user_id,
        data.sku_id,
        date_format(ts, 'yyyy-MM-dd'),
        ts,
        if( type = 'insert', data.sku_num, data.sku_num - old['sku_num']) -- 自动转换
    from ods_cart_info_inc
    where dt = '2022-06-09'
    and (
        type = 'insert'
        or
        (
            type = 'update'
                and
            array_contains(map_keys(old), 'sku_num')
                and
            data.sku_num > cast(old['sku_num'] as bigint)
        )
    );
    
    -- from_unixtime:0时区的时间
    select
        ts,
        from_unixtime(ts, 'yyyy-MM-dd HH:mm:ss'),
        date_format(from_utc_timestamp(ts * 1000, 'GMT+8'), 'yyyy-MM-dd HH:mm:ss')
    from ods_cart_info_inc
    where dt = '2022-06-08'
    and type = 'bootstrap-insert';
    
    -- 交易域下单事务事实表
        -- 交易域
        -- 下单
            -- 用户 + 时间 + 商品 + 订单 + 商品数量 + 商品金额
        -- 事务事实表
        -- 建表语句
    DROP TABLE IF EXISTS dwd_trade_order_detail_inc;
    CREATE EXTERNAL TABLE dwd_trade_order_detail_inc
    (
        `id`                     STRING COMMENT '编号',
        `order_id`              STRING COMMENT '订单ID',
        `user_id`               STRING COMMENT '用户ID',
        `sku_id`                STRING COMMENT '商品ID',
        `province_id`          STRING COMMENT '省份ID',
        `activity_id`          STRING COMMENT '参与活动ID',
        `activity_rule_id`    STRING COMMENT '参与活动规则ID',
        `coupon_id`             STRING COMMENT '使用优惠券ID',
        `date_id`               STRING COMMENT '下单日期ID',
        `create_time`           STRING COMMENT '下单时间',
        `sku_num`                BIGINT COMMENT '商品数量',
        `split_original_amount` DECIMAL(16, 2) COMMENT '原始价格',
        `split_activity_amount` DECIMAL(16, 2) COMMENT '活动优惠分摊',
        `split_coupon_amount`   DECIMAL(16, 2) COMMENT '优惠券优惠分摊',
        `split_total_amount`    DECIMAL(16, 2) COMMENT '最终价格分摊'
    ) COMMENT '交易域下单事务事实表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dwd/dwd_trade_order_detail_inc/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- 数据装载
        -- load
        -- save
    
    -- 首日:历史数据
    insert overwrite table dwd_trade_order_detail_inc partition (dt)
    select
        od.`id`                  ,--STRING COMMENT '编号',
        `order_id`               ,--STRING COMMENT '订单ID',
        `user_id`                ,--STRING COMMENT '用户ID',
        `sku_id`                 ,--STRING COMMENT '商品ID',
        `province_id`            ,--STRING COMMENT '省份ID',
        `activity_id`            ,--STRING COMMENT '参与活动ID',
        `activity_rule_id`       ,--STRING COMMENT '参与活动规则ID',
        `coupon_id`              ,--STRING COMMENT '使用优惠券ID',
        `date_id`                ,--STRING COMMENT '下单日期ID',
        `create_time`            ,--STRING COMMENT '下单时间',
        `sku_num`                ,--BIGINT COMMENT '商品数量',
        `split_original_amount`  ,--DECIMAL(16, 2) COMMENT '原始价格',
        `split_activity_amount`  ,--DECIMAL(16, 2) COMMENT '活动优惠分摊',
        `split_coupon_amount`    ,--DECIMAL(16, 2) COMMENT '优惠券优惠分摊',
        `split_total_amount`     ,--DECIMAL(16, 2) COMMENT '最终价格分摊'
        date_id
    from (
        select
            data.`id`                    ,--STRING COMMENT '编号',
            data.`order_id`              ,--STRING COMMENT '订单ID',
            --data.`user_id`               ,--STRING COMMENT '用户ID',
            data.`sku_id`                ,--STRING COMMENT '商品ID',
            --data.`province_id`           ,--STRING COMMENT '省份ID',
            --data.`activity_id`           ,--STRING COMMENT '参与活动ID',
            --data.`activity_rule_id`      ,--STRING COMMENT '参与活动规则ID',
            --data.`coupon_id`             ,--STRING COMMENT '使用优惠券ID',
            --data.`date_id`               ,--STRING COMMENT '下单日期ID',
            --data.`create_time`           ,--STRING COMMENT '下单时间',
            data.`sku_num`               ,--BIGINT COMMENT '商品数量',
            data.`sku_num` * data.`order_price` `split_original_amount` ,--DECIMAL(16, 2) COMMENT '原始价格',
            nvl(data.`split_activity_amount`, 0) split_activity_amount ,--DECIMAL(16, 2) COMMENT '活动优惠分摊',
            nvl(data.`split_coupon_amount`, 0) split_coupon_amount ,--DECIMAL(16, 2) COMMENT '优惠券优惠分摊',
            data.`split_total_amount`     --DECIMAL(16, 2) COMMENT '最终价格分摊'
        from ods_order_detail_inc
        where dt = '2022-06-08'
        and type = 'bootstrap-insert'
    ) od
    left join (
        select
            data.id,
            data.user_id,
            data.province_id,
            date_format(data.create_time, 'yyyy-MM-dd') date_id,
            data.create_time
        from ods_order_info_inc
        where dt = '2022-06-08'
        and type = 'bootstrap-insert'
    ) oi on od.order_id = oi.id
    left join (
        select
            data.order_detail_id,
            data.activity_id,
            data.activity_rule_id
        from ods_order_detail_activity_inc
        where dt = '2022-06-08'
        and type = 'bootstrap-insert'
    ) act on od.id = act.order_detail_id
    left join (
        select
            data.order_detail_id,
            data.coupon_id
        from ods_order_detail_coupon_inc
        where dt = '2022-06-08'
        and type = 'bootstrap-insert'
    ) cp on od.id = cp.order_detail_id;
    
    
    -- 每日:当天数据
    insert overwrite table dwd_trade_order_detail_inc partition (dt='2022-06-09')
    select
        od.`id`                  ,--STRING COMMENT '编号',
        `order_id`               ,--STRING COMMENT '订单ID',
        `user_id`                ,--STRING COMMENT '用户ID',
        `sku_id`                 ,--STRING COMMENT '商品ID',
        `province_id`            ,--STRING COMMENT '省份ID',
        `activity_id`            ,--STRING COMMENT '参与活动ID',
        `activity_rule_id`       ,--STRING COMMENT '参与活动规则ID',
        `coupon_id`              ,--STRING COMMENT '使用优惠券ID',
        `date_id`                ,--STRING COMMENT '下单日期ID',
        `create_time`            ,--STRING COMMENT '下单时间',
        `sku_num`                ,--BIGINT COMMENT '商品数量',
        `split_original_amount`  ,--DECIMAL(16, 2) COMMENT '原始价格',
        `split_activity_amount`  ,--DECIMAL(16, 2) COMMENT '活动优惠分摊',
        `split_coupon_amount`    ,--DECIMAL(16, 2) COMMENT '优惠券优惠分摊',
        `split_total_amount`      --DECIMAL(16, 2) COMMENT '最终价格分摊'
    from (
        select
            data.`id`                    ,--STRING COMMENT '编号',
            data.`order_id`              ,--STRING COMMENT '订单ID',
            --data.`user_id`               ,--STRING COMMENT '用户ID',
            data.`sku_id`                ,--STRING COMMENT '商品ID',
            --data.`province_id`           ,--STRING COMMENT '省份ID',
            --data.`activity_id`           ,--STRING COMMENT '参与活动ID',
            --data.`activity_rule_id`      ,--STRING COMMENT '参与活动规则ID',
            --data.`coupon_id`             ,--STRING COMMENT '使用优惠券ID',
            --data.`date_id`               ,--STRING COMMENT '下单日期ID',
            --data.`create_time`           ,--STRING COMMENT '下单时间',
            data.`sku_num`               ,--BIGINT COMMENT '商品数量',
            data.`sku_num` * data.`order_price` `split_original_amount` ,--DECIMAL(16, 2) COMMENT '原始价格',
            nvl(data.`split_activity_amount`, 0) split_activity_amount ,--DECIMAL(16, 2) COMMENT '活动优惠分摊',
            nvl(data.`split_coupon_amount`, 0) split_coupon_amount ,--DECIMAL(16, 2) COMMENT '优惠券优惠分摊',
            data.`split_total_amount`     --DECIMAL(16, 2) COMMENT '最终价格分摊'
        from ods_order_detail_inc
        where dt = '2022-06-09'
        and type = 'insert' -- 只有insert
    ) od
    left join (
        select
            data.id,
            data.user_id,
            data.province_id,
            date_format(data.create_time, 'yyyy-MM-dd') date_id,
            data.create_time
        from ods_order_info_inc
        where dt = '2022-06-09'
        and type = 'insert' -- 此处假设 update操作不会修改我们想要的字段
    ) oi on od.order_id = oi.id
    left join (
        select
            data.order_detail_id,
            data.activity_id,
            data.activity_rule_id
        from ods_order_detail_activity_inc
        where dt = '2022-06-09'
        and type = 'insert' -- 只有insert
    ) act on od.id = act.order_detail_id
    left join (
        select
            data.order_detail_id,
            data.coupon_id
        from ods_order_detail_coupon_inc
        where dt = '2022-06-09'
        and type = 'insert'
    ) cp on od.id = cp.order_detail_id;
    
    -- 交易域支付成功事务事实表:最细粒度
        -- 交易域
        -- 支付成功
            -- 用户 + 时间 + 订单 + 商品 + 支付金额
        -- 事务事实表
        -- 建表语句
        -- 维度表是否应该创建
            -- 原则上来讲,每一个维度都应该创建一张表
                -- 但是如果维度比较简单,数据少,应用场景少,那么无需创建维度表,可以直接将维度声明在事实表,一般称之为'维度退化'
    DROP TABLE IF EXISTS dwd_trade_pay_detail_suc_inc;
    CREATE EXTERNAL TABLE dwd_trade_pay_detail_suc_inc
    (
        `id`                      STRING COMMENT '编号',
        `order_id`               STRING COMMENT '订单ID',
        `user_id`                STRING COMMENT '用户ID',
        `sku_id`                 STRING COMMENT 'SKU_ID',
        `province_id`           STRING COMMENT '省份ID',
        `activity_id`           STRING COMMENT '参与活动ID',
        `activity_rule_id`     STRING COMMENT '参与活动规则ID',
        `coupon_id`              STRING COMMENT '使用优惠券ID',
        `payment_type_code`     STRING COMMENT '支付类型编码',
        `payment_type_name`     STRING COMMENT '支付类型名称',
        `date_id`                STRING COMMENT '支付日期ID',
        `callback_time`         STRING COMMENT '支付成功时间',
        `sku_num`                 BIGINT COMMENT '商品数量',
        `split_original_amount` DECIMAL(16, 2) COMMENT '应支付原始金额',
        `split_activity_amount` DECIMAL(16, 2) COMMENT '支付活动优惠分摊',
        `split_coupon_amount`   DECIMAL(16, 2) COMMENT '支付优惠券优惠分摊',
        `split_payment_amount`  DECIMAL(16, 2) COMMENT '支付金额' -- 支付金额与下单金额不是一回事
    ) COMMENT '交易域支付成功事务事实表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dwd/dwd_trade_pay_detail_suc_inc/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- 首日数据装载
    insert overwrite table dwd_trade_pay_detail_suc_inc partition (dt)
    select
        od.`id`                    ,--   STRING COMMENT '编号',
        od.`order_id`              ,--  STRING COMMENT '订单ID',
        `user_id`               ,--  STRING COMMENT '用户ID',
        `sku_id`                ,--  STRING COMMENT 'SKU_ID',
        `province_id`           ,-- STRING COMMENT '省份ID',
        `activity_id`           ,-- STRING COMMENT '参与活动ID',
        `activity_rule_id`      ,--STRING COMMENT '参与活动规则ID',
        `coupon_id`             ,--  STRING COMMENT '使用优惠券ID',
        `payment_type_code`     ,-- STRING COMMENT '支付类型编码',
        `payment_type_name`     ,-- STRING COMMENT '支付类型名称',
        `date_id`               ,--  STRING COMMENT '支付日期ID',
        `callback_time`         ,-- STRING COMMENT '支付成功时间',
        `sku_num`               ,--   BIGINT COMMENT '商品数量',
        `split_original_amount` ,-- DECIMAL(16, 2) COMMENT '应支付原始金额',
        `split_activity_amount` ,-- DECIMAL(16, 2) COMMENT '支付活动优惠分摊',
        `split_coupon_amount`   ,-- DECIMAL(16, 2) COMMENT '支付优惠券优惠分摊',
        `split_payment_amount`  ,-- DECIMAL(16, 2) COMMENT '支付金额'
        date_id
    from (
        select
            data.`id`                    ,--   STRING COMMENT '编号',
            data.`order_id`              ,--  STRING COMMENT '订单ID',
            --data.`user_id`               ,--  STRING COMMENT '用户ID',
            data.`sku_id`                ,--  STRING COMMENT 'SKU_ID',
            --data.`province_id`           ,-- STRING COMMENT '省份ID',
            --data.`activity_id`           ,-- STRING COMMENT '参与活动ID',
            --data.`activity_rule_id`      ,--STRING COMMENT '参与活动规则ID',
            --data.`coupon_id`             ,--  STRING COMMENT '使用优惠券ID',
            --data.`payment_type_code`     ,-- STRING COMMENT '支付类型编码',
            --data.`payment_type_name`     ,-- STRING COMMENT '支付类型名称',
            --data.`date_id`               ,--  STRING COMMENT '支付日期ID',
            --data.`callback_time`         ,-- STRING COMMENT '支付成功时间',
            data.`sku_num`               ,--   BIGINT COMMENT '商品数量',
            data.sku_num * data.order_price `split_original_amount` ,-- DECIMAL(16, 2) COMMENT '应支付原始金额',
            data.`split_activity_amount` ,-- DECIMAL(16, 2) COMMENT '支付活动优惠分摊',
            data.`split_coupon_amount`    -- DECIMAL(16, 2) COMMENT '支付优惠券优惠分摊',
            --data.`split_payment_amount`   -- DECIMAL(16, 2) COMMENT '支付金额'
        from ods_order_detail_inc
        where dt = '2022-06-08'
        and type = 'bootstrap-insert'
    ) od
    join (  --  join !!! 有订单详情但不一定有支付信息,没有支付信息的不要
        select
            data.order_id,
            data.payment_type payment_type_code,
            date_format(data.callback_time, 'yyyy-MM-dd') date_id,
            data.callback_time,
            data.total_amount split_payment_amount
        from ods_payment_info_inc
        where dt = '2022-06-08'
        and type = 'bootstrap-insert'
        and data.payment_status = '1602'
    ) pay on od.order_id = pay.order_id
    left join (
        select
            data.id,
            data.user_id,
            data.province_id
        from ods_order_info_inc
        where dt = '2022-06-08'
        and type = 'bootstrap-insert'
    ) oi on od.order_id = oi.id
    left join (
        select
            data.order_detail_id,
            data.activity_id,
            data.activity_rule_id
        from ods_order_detail_activity_inc
        where dt = '2022-06-08'
        and type = 'bootstrap-insert'
    ) act on od.id = act.order_detail_id
    left join (
        select
            data.order_detail_id,
            data.coupon_id
        from ods_order_detail_coupon_inc
        where dt = '2022-06-08'
        and type = 'bootstrap-insert'
    ) cp on od.id = cp.order_detail_id
    left join (
        select
            dic_code,
            dic_name payment_type_name
        from ods_base_dic_full
        where dt = '2022-06-08'
        and parent_code = '11'
    ) dic on pay.payment_type_code = dic.dic_code;
    
    
    -- 每日数据装载
    insert overwrite table dwd_trade_pay_detail_suc_inc partition (dt='2022-06-09')
    select
        od.`id`                    ,--   STRING COMMENT '编号',
        od.`order_id`              ,--  STRING COMMENT '订单ID',
        `user_id`               ,--  STRING COMMENT '用户ID',
        `sku_id`                ,--  STRING COMMENT 'SKU_ID',
        `province_id`           ,-- STRING COMMENT '省份ID',
        `activity_id`           ,-- STRING COMMENT '参与活动ID',
        `activity_rule_id`      ,--STRING COMMENT '参与活动规则ID',
        `coupon_id`             ,--  STRING COMMENT '使用优惠券ID',
        `payment_type_code`     ,-- STRING COMMENT '支付类型编码',
        `payment_type_name`     ,-- STRING COMMENT '支付类型名称',
        `date_id`               ,--  STRING COMMENT '支付日期ID',
        `callback_time`         ,-- STRING COMMENT '支付成功时间',
        `sku_num`               ,--   BIGINT COMMENT '商品数量',
        `split_original_amount` ,-- DECIMAL(16, 2) COMMENT '应支付原始金额',
        `split_activity_amount` ,-- DECIMAL(16, 2) COMMENT '支付活动优惠分摊',
        `split_coupon_amount`   ,-- DECIMAL(16, 2) COMMENT '支付优惠券优惠分摊',
        `split_payment_amount`   -- DECIMAL(16, 2) COMMENT '支付金额'
    from (
        select
            data.`id`                    ,--   STRING COMMENT '编号',
            data.`order_id`              ,--  STRING COMMENT '订单ID',
            --data.`user_id`               ,--  STRING COMMENT '用户ID',
            data.`sku_id`                ,--  STRING COMMENT 'SKU_ID',
            --data.`province_id`           ,-- STRING COMMENT '省份ID',
            --data.`activity_id`           ,-- STRING COMMENT '参与活动ID',
            --data.`activity_rule_id`      ,--STRING COMMENT '参与活动规则ID',
            --data.`coupon_id`             ,--  STRING COMMENT '使用优惠券ID',
            --data.`payment_type_code`     ,-- STRING COMMENT '支付类型编码',
            --data.`payment_type_name`     ,-- STRING COMMENT '支付类型名称',
            --data.`date_id`               ,--  STRING COMMENT '支付日期ID',
            --data.`callback_time`         ,-- STRING COMMENT '支付成功时间',
            data.`sku_num`               ,--   BIGINT COMMENT '商品数量',
            data.sku_num * data.order_price `split_original_amount` ,-- DECIMAL(16, 2) COMMENT '应支付原始金额',
            data.`split_activity_amount` ,-- DECIMAL(16, 2) COMMENT '支付活动优惠分摊',
            data.`split_coupon_amount`    -- DECIMAL(16, 2) COMMENT '支付优惠券优惠分摊',
            --data.`split_payment_amount`   -- DECIMAL(16, 2) COMMENT '支付金额'
        from ods_order_detail_inc
        where (dt = '2022-06-09' or dt = date_sub('2022-06-09', 1))
        and (type = 'insert' or type = 'bootstrap-insert')
    ) od
    join (  --  join !!! 有订单详情但不一定有支付信息,没有支付信息的不要
        select
            data.order_id,
            data.payment_type payment_type_code,
            date_format(data.callback_time, 'yyyy-MM-dd') date_id,
            data.callback_time,
            data.total_amount split_payment_amount
        from ods_payment_info_inc
        where dt = '2022-06-09'
        and type = 'update'
        and array_contains(map_keys(old), 'payment_status')
        and data.payment_status = '1602'
    ) pay on od.order_id = pay.order_id
    left join (
        select
            data.id,
            data.user_id,
            data.province_id
        from ods_order_info_inc
        where (dt = '2022-06-09' or dt = date_sub('2022-06-09', 1))
        and (type = 'insert' or type = 'bootstrap-insert')
    ) oi on od.order_id = oi.id
    left join (
        select
            data.order_detail_id,
            data.activity_id,
            data.activity_rule_id
        from ods_order_detail_activity_inc
        where (dt = '2022-06-09' or dt = date_sub('2022-06-09', 1))
        and (type = 'insert' or type = 'bootstrap-insert')
    ) act on od.id = act.order_detail_id
    left join (
        select
            data.order_detail_id,
            data.coupon_id
        from ods_order_detail_coupon_inc
        where (dt = '2022-06-09' or dt = date_sub('2022-06-09', 1))
        and (type = 'insert' or type = 'bootstrap-insert')
    ) cp on od.id = cp.order_detail_id
    left join (
        select
            dic_code,
            dic_name payment_type_name
        from ods_base_dic_full
        where dt = '2022-06-09'
        and parent_code = '11'
    ) dic on pay.payment_type_code = dic.dic_code;
    
    -- 交易域购物车周期快照事实表
        -- 交易域
        -- 购物车
        -- 周期快照事实表
            -- 特殊的需求:各品类商品购物车存量(Top3)
                -- zhangsan: 鞋  生活用品  5
                -- zhangsan:手机 电子产品  1
                -- lisi:    衣服 生活用品  1
            ---------------------------------
                -- 生活用品[6]
                -- 电子产品[1]
            -- 实现思路:行为数据(事实表) + 状态数据(维度表)
                -- dwd_trade_cart_add_inc(加购) + dim_sku_full
                -- dwd_trade_cart_sub_inc(减购) + dim_sku_full
                    -- 1001 [1, 2, 5, 6]
                    -- 1001 [3, 2, 1]
                    -- [join] 1001 add(14) sub(6) => [1001 storage(8)]
            -- 特殊的需求不需要特殊计算,因为效率太低,那么可以直接从业务数据中获取特殊字段,比如存量字段(库存、余额……)
                -- 特殊字段不需要进行多张表的关联计算,直接从业务数据库中周期性地获取即可
        -- 建表语句
    DROP TABLE IF EXISTS dwd_trade_cart_full;
    CREATE EXTERNAL TABLE dwd_trade_cart_full
    (
        `id`         STRING COMMENT '编号',
        `user_id`   STRING COMMENT '用户ID',
        `sku_id`    STRING COMMENT 'SKU_ID',
        `sku_name`  STRING COMMENT '商品名称',
        `sku_num`   BIGINT COMMENT '现存商品件数'
    ) COMMENT '交易域购物车周期快照事实表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dwd/dwd_trade_cart_full/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- 度量值的类型
        -- 可加事实:度量值可加
        -- 半可加事实:度量值在某些场景中可加,在某些场景不可加
        -- 不可加事实:比率型
    
    -- 数据装载(full - tsv)
    insert overwrite table dwd_trade_cart_full partition (dt = '2022-06-08')
    select
        `id`        ,--STRING COMMENT '编号',
        `user_id`   ,--STRING COMMENT '用户ID',
        `sku_id`    ,--STRING COMMENT 'SKU_ID',
        `sku_name`  ,--STRING COMMENT '商品名称',
        `sku_num`    --BIGINT COMMENT '现存商品件数'
    from ods_cart_info_full
    where dt = '2022-06-08'
    and is_ordered = '0';
    
    -- 交易域交易流程累积快照事实表
        -- 交易域
        -- 交易流程
        -- 累积快照事实表
            -- 特殊的需求:下单到支付时间间隔平均值
            -- 将一个流程中的多个行为的状态数据累积到一张表中
        -- 建表语句
            -- 行为和行为之间的关系,粒度不是越细越好
    DROP TABLE IF EXISTS dwd_trade_trade_flow_acc;
    CREATE EXTERNAL TABLE dwd_trade_trade_flow_acc
    (
        `order_id`               STRING COMMENT '订单ID',
        `user_id`                STRING COMMENT '用户ID',
        `province_id`           STRING COMMENT '省份ID',
        `order_date_id`         STRING COMMENT '下单日期ID',
        `order_time`             STRING COMMENT '下单时间',
        `payment_date_id`        STRING COMMENT '支付日期ID',
        `payment_time`           STRING COMMENT '支付时间',
        `finish_date_id`         STRING COMMENT '确认收货日期ID',
        `finish_time`             STRING COMMENT '确认收货时间',
        `order_original_amount` DECIMAL(16, 2) COMMENT '下单原始价格',
        `order_activity_amount` DECIMAL(16, 2) COMMENT '下单活动优惠分摊',
        `order_coupon_amount`   DECIMAL(16, 2) COMMENT '下单优惠券优惠分摊',
        `order_total_amount`    DECIMAL(16, 2) COMMENT '下单最终价格分摊',
        `payment_amount`         DECIMAL(16, 2) COMMENT '支付金额'
    ) COMMENT '交易域交易流程累积快照事实表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dwd/dwd_trade_trade_flow_acc/'
    TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- 加载数据
    -- 首日
        -- 保存数据时,分区策略
            -- 哪天的数据存放到哪天的分区
                -- 使用下单日期 order_date_id 作为分区
        -- 如果表中存在多个和业务相关的时间字段,一般会选择其中的一个业务时间作为分区字段
            -- 一般选择时间靠后的字段作为分区字段
                -- DIM_USER_ZIP
            -- 存在一个问题,最后一个时间字段可能没值,一般不会采用null来表示分区,会采用时间极大值 9999-12-31
    insert overwrite table dwd_trade_trade_flow_acc partition (dt)
    select
        oi.id `order_id`        ,--  STRING COMMENT '订单ID',
        `user_id`               ,--  STRING COMMENT '用户ID',
        `province_id`           ,-- STRING COMMENT '省份ID',
        `order_date_id`         ,-- STRING COMMENT '下单日期ID',
        `order_time`            ,--  STRING COMMENT '下单时间',
        `payment_date_id`       ,--  STRING COMMENT '支付日期ID',
        `payment_time`          ,--  STRING COMMENT '支付时间',
        `finish_date_id`        ,--  STRING COMMENT '确认收货日期ID',
        `finish_time`           ,--   STRING COMMENT '确认收货时间',
        `order_original_amount` ,-- DECIMAL(16, 2) COMMENT '下单原始价格',
        `order_activity_amount` ,-- DECIMAL(16, 2) COMMENT '下单活动优惠分摊',
        `order_coupon_amount`   ,-- DECIMAL(16, 2) COMMENT '下单优惠券优惠分摊',
        `order_total_amount`    ,-- DECIMAL(16, 2) COMMENT '下单最终价格分摊',
        `payment_amount`        ,--  DECIMAL(16, 2) COMMENT '支付金额'
        nvl(finish_date_id, '9999-12-31')
    from (
        select
            data.id,
            data.user_id,
            data.province_id,
            date_format(data.create_time, 'yyyy-MM-dd') order_date_id,
            data.create_time order_time,
            data.original_total_amount order_original_amount,
            data.activity_reduce_amount order_activity_amount,
            data.coupon_reduce_amount order_coupon_amount,
            data.total_amount order_total_amount
        from ods_order_info_inc
        where dt = '2022-06-08'
        and type = 'bootstrap-insert'
    ) oi
    left join (
        select
            data.order_id,
            date_format(data.callback_time, 'yyyy-MM-dd') payment_date_id,
            data.callback_time payment_time,
            data.total_amount payment_amount
        from ods_payment_info_inc
        where dt = '2022-06-08'
        and type = 'bootstrap-insert'
        and data.payment_status = '1602'
    ) pay on oi.id = pay.order_id
    left join (
        -- 订单状态流水表
        select
            data.order_id,
            date_format(data.create_time, 'yyyy-MM-dd') finish_date_id,
            data.create_time finish_time
        from ods_order_status_log_inc
        where dt = '2022-06-08'
        and type = 'bootstrap-insert'
        and data.order_status = '1004'
    ) log on oi.id = log.order_id;
    
    -- 分区策略
        -- 查询的数据如何存储到表的分区中
            -- 查询数据的效率,数据有效
    
        -- ODS层
            -- 一天采集到的数据就存储到表的一天的分区
    
        -- DIM层
            -- 全量:每天一份全量数据
            -- 拉链:会采用结束时间作为分区字段(null -> 9999-12-31)
    
        -- DWD层
            -- 事务型事实表:一天的业务行为数据存到一天的分区中
            -- 周期型快照事实表:将每一天的全部状态数据保存到这一天的分区中(行为 -> 状态)
            -- 累计型快照事实表:将业务流程中最后的时间字段作为分区字段
    
    -- 每日
        -- [insert order] * [update payment] * [update finish]
            -- union all
        -- [old order] * [update payment] * [update finish]
        -- (insert order union all old order) * payment * finish
    
    insert overwrite table dwd_trade_trade_flow_acc partition (dt)
    select
        oi.`order_id`              ,-- STRING COMMENT '订单ID',
        `user_id`               ,-- STRING COMMENT '用户ID',
        `province_id`           ,--STRING COMMENT '省份ID',
        `order_date_id`         ,--STRING COMMENT '下单日期ID',
        `order_time`            ,-- STRING COMMENT '下单时间',
        if(pay.`payment_time` is not null, pay.`payment_date_id`, oi.`payment_date_id`)      ,--  STRING COMMENT '支付日期ID',
        if(pay.`payment_time` is not null, pay.`payment_time`, oi.`payment_time`)         ,--  STRING COMMENT '支付时间',
        if(log.finish_time is not null, log.finish_date_id, null)        ,-- STRING COMMENT '确认收货日期ID',
        if(log.finish_time is not null, log.finish_time, null)           ,--  STRING COMMENT '确认收货时间',
        `order_original_amount` ,--DECIMAL(16, 2) COMMENT '下单原始价格',
        `order_activity_amount` ,--DECIMAL(16, 2) COMMENT '下单活动优惠分摊',
        `order_coupon_amount`   ,--DECIMAL(16, 2) COMMENT '下单优惠券优惠分摊',
        `order_total_amount`    ,--DECIMAL(16, 2) COMMENT '下单最终价格分摊',
        if(pay.`payment_time` is not null, pay.`payment_amount`, oi.payment_amount)         ,-- DECIMAL(16, 2) COMMENT '支付金额'
        if(log.finish_time is not null, log.finish_date_id, '9999-12-31')
    from (
        select
            `order_id`             ,--  STRING COMMENT '订单ID',
            `user_id`              ,--  STRING COMMENT '用户ID',
            `province_id`          ,-- STRING COMMENT '省份ID',
            `order_date_id`        ,-- STRING COMMENT '下单日期ID',
            `order_time`           ,--  STRING COMMENT '下单时间',
            `payment_date_id`      ,-- STRING COMMENT '支付日期ID',
            `payment_time`         ,-- STRING COMMENT '支付时间',
            `finish_date_id`       ,--  STRING COMMENT '确认收货日期ID',
            `finish_time`          ,--   STRING COMMENT '确认收货时间',
            `order_original_amount`,-- DECIMAL(16, 2) COMMENT '下单原始价格',
            `order_activity_amount`,-- DECIMAL(16, 2) COMMENT '下单活动优惠分摊',
            `order_coupon_amount`  ,-- DECIMAL(16, 2) COMMENT '下单优惠券优惠分摊',
            `order_total_amount`   ,-- DECIMAL(16, 2) COMMENT '下单最终价格分摊',
            `payment_amount`        --  DECIMAL(16, 2) COMMENT '支付金额'
        from dwd_trade_trade_flow_acc
        where dt = '9999-12-31'
        union all
        select
            data.id,
            data.user_id,
            data.province_id,
            date_format(data.create_time, 'yyyy-MM-dd') order_date_id,
            data.create_time order_time,
            null,
            null,
            null,
            null,
            data.original_total_amount order_original_amount,
            data.activity_reduce_amount order_activity_amount,
            data.coupon_reduce_amount order_coupon_amount,
            data.total_amount order_total_amount,
            null
        from ods_order_info_inc
        where dt = '2022-06-09'
        and type = 'insert'
    ) oi
    left join (
        select
            data.order_id,
            date_format(data.callback_time, 'yyyy-MM-dd') payment_date_id,
            data.callback_time payment_time,
            data.total_amount payment_amount
        from ods_payment_info_inc
        where dt = '2022-06-09'
        and type = 'update'
        and array_contains(map_keys(old), 'payment')
    ) pay on oi.order_id = pay.order_id
    left join (
        select
            data.order_id,
            date_format(data.create_time, 'yyyy-MM-dd') finish_date_id,
            data.create_time finish_time
        from ods_order_status_log_inc
        where dt = '2022-06-09'
        and type = 'insert'
        and data.order_status = '1004'
    ) log;
    
    
    -- 工具域优惠券使用(支付)事务事实表
        -- 工具域
        -- 优惠券使用(支付)
            -- 用户 + 时间 + 订单 + 优惠券 + (次数)
        -- 事务事实表
    DROP TABLE IF EXISTS dwd_tool_coupon_used_inc;
    CREATE EXTERNAL TABLE dwd_tool_coupon_used_inc
    (
        `id`           STRING COMMENT '编号',
        `coupon_id`    STRING COMMENT '优惠券ID',
        `user_id`      STRING COMMENT '用户ID',
        `order_id`     STRING COMMENT '订单ID',
        `date_id`      STRING COMMENT '日期ID',
        `payment_time` STRING COMMENT '使用(支付)时间'
    ) COMMENT '优惠券使用(支付)事务事实表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dwd/dwd_tool_coupon_used_inc/'
        TBLPROPERTIES ("orc.compress" = "snappy");
    
    -- 数据装载
    -- 首日
    insert overwrite table dwd_tool_coupon_used_inc partition (dt)
    select
        data.`id`           ,--STRING COMMENT '编号',
        data.`coupon_id`    ,--STRING COMMENT '优惠券ID',
        data.`user_id`      ,--STRING COMMENT '用户ID',
        data.`order_id`     ,--STRING COMMENT '订单ID',
        date_format(data.used_time, 'yyyy-MM-dd') `date_id`      ,--STRING COMMENT '日期ID',
        data.used_time `payment_time` ,--STRING COMMENT '使用(支付)时间'
        date_format(data.used_time, 'yyyy-MM-dd')
    from ods_coupon_use_inc
    where dt = '2022-06-08'
    and type = 'bootstrap-insert'
    and data.used_time is not null;
    
    -- 每日
    insert overwrite table dwd_tool_coupon_used_inc partition (dt = '2022-06-09')
    select
        data.`id`           ,--STRING COMMENT '编号',
        data.`coupon_id`    ,--STRING COMMENT '优惠券ID',
        data.`user_id`      ,--STRING COMMENT '用户ID',
        data.`order_id`     ,--STRING COMMENT '订单ID',
        date_format(data.used_time, 'yyyy-MM-dd') `date_id`      ,--STRING COMMENT '日期ID',
        data.used_time `payment_time` --STRING COMMENT '使用(支付)时间'
    from ods_coupon_use_inc
    where dt = '2022-06-09'
    and type = 'update'
    -- and array_contains(map_keys(old), 'used_time') -- 同下
    and data.used_time is not null;
    
    -- 互动域收藏商品事务事实表
        -- 互动域
        -- 收藏商品
            -- 用户 + 时间 + 商品
        -- 事务事实表
        -- 建表语句
    DROP TABLE IF EXISTS dwd_interaction_favor_add_inc;
    CREATE EXTERNAL TABLE dwd_interaction_favor_add_inc
    (
        `id`          STRING COMMENT '编号',
        `user_id`     STRING COMMENT '用户ID',
        `sku_id`      STRING COMMENT 'SKU_ID',
        `date_id`     STRING COMMENT '日期ID',
        `create_time` STRING COMMENT '收藏时间'
    ) COMMENT '互动域收藏商品事务事实表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dwd/dwd_interaction_favor_add_inc/'
        TBLPROPERTIES ("orc.compress" = "snappy");
    
    -- 数据装载
    insert overwrite table dwd_interaction_favor_add_inc partition (dt)
    select
        data.id,
        data.user_id,
        data.sku_id,
        date_format(data.create_time, 'yyyy-MM-dd') date_id,
        data.create_time,
        date_format(data.create_time, 'yyyy-MM-dd')
    from ods_favor_info_inc
    where dt = '2022-06-08'
    and type = 'bootstrap-insert';
    --and data.is_cancel = '0' -- 曾经收藏过也是收藏行为
    -- id user_id ... is_cancel
    -- 1   1001           0
    -- 2   1002           1    -- 这条数据曾经被收藏过
    
    insert overwrite table dwd_interaction_favor_add_inc partition (dt = '2022-06-09')
    select
        data.id,
        data.user_id,
        data.sku_id,
        date_format(data.create_time, 'yyyy-MM-dd') date_id,
        data.create_time
    from ods_favor_info_inc
    where dt = '2022-06-09'
    and type = 'insert';
    
    -- 流量域页面浏览事务事实表
        -- 流量域
        -- 页面浏览
            -- 用户 + 时间 + 上一个页面 + 当前页面 + 停留时间
            -- 日志
        -- 事务事实表
        -- 建表语句
    DROP TABLE IF EXISTS dwd_traffic_page_view_inc;
    CREATE EXTERNAL TABLE dwd_traffic_page_view_inc
    (
        `province_id`    STRING COMMENT '省份ID',
        `brand`           STRING COMMENT '手机品牌',
        `channel`         STRING COMMENT '渠道',
        `is_new`          STRING COMMENT '是否首次启动',
        `model`           STRING COMMENT '手机型号',
        `mid_id`          STRING COMMENT '设备ID', -- 用户
        `operate_system` STRING COMMENT '操作系统',
        `user_id`         STRING COMMENT '会员ID',  -- 登录后的ID
        `version_code`   STRING COMMENT 'APP版本号',
        `page_item`       STRING COMMENT '目标ID',
        `page_item_type` STRING COMMENT '目标类型',
        `last_page_id`    STRING COMMENT '上页ID',
        `page_id`          STRING COMMENT '页面ID ',
        `from_pos_id`     STRING COMMENT '点击坑位ID',
        `from_pos_seq`    STRING COMMENT '点击坑位位置',
        `refer_id`         STRING COMMENT '营销渠道ID',
        `date_id`          STRING COMMENT '日期ID',
        `view_time`       STRING COMMENT '跳入时间',
        `session_id`      STRING COMMENT '所属会话ID',
        `during_time`     BIGINT COMMENT '持续时间毫秒'
    ) COMMENT '流量域页面浏览事务事实表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dwd/dwd_traffic_page_view_inc'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- 数据装载
        -- 日志表的数据分为两大类
            -- 页面浏览日志
            -- APP启动日志
        -- Hive Bug
            -- 升级(扩展)
    set hive.cbo.enable=false;
    insert overwrite table dwd_traffic_page_view_inc partition (dt='2022-06-08')
    select
        common.ar `province_id`     ,--STRING COMMENT '省份ID',
        common.ba `brand`           ,--STRING COMMENT '手机品牌',
        common.ch `channel`         ,--STRING COMMENT '渠道',
        common.`is_new`          ,--STRING COMMENT '是否首次启动',
        common.md `model`           ,--STRING COMMENT '手机型号',
        common.mid `mid_id`          ,--STRING COMMENT '设备ID', -- 用户
        common.os `operate_system`  ,--STRING COMMENT '操作系统',
        common.uid `user_id`         ,--STRING COMMENT '会员ID',  -- 登录后的ID
        common.vc `version_code`     ,--STRING COMMENT 'APP版本号',
        page.item `page_item`       ,--STRING COMMENT '目标ID',
        page.item_type `page_item_type`  ,--STRING COMMENT '目标类型',
        page.`last_page_id`    ,--STRING COMMENT '上页ID',
        page.`page_id`         ,--STRING COMMENT '页面ID ',
        page.`from_pos_id`     ,--STRING COMMENT '点击坑位ID',
        page.`from_pos_seq`    ,--STRING COMMENT '点击坑位位置',
        page.`refer_id`        ,--STRING COMMENT '营销渠道ID',
        date_format(from_utc_timestamp(ts, 'GMT+8'), 'yyyy-MM-dd') `date_id`          ,--STRING COMMENT '日期ID',
        date_format(from_utc_timestamp(ts, 'GMT+8'), 'yyyy-MM-dd HH:mm:ss') `view_time`        ,--STRING COMMENT '跳入时间',
        common.sid `session_id`       ,--STRING COMMENT '所属会话ID',
        page.`during_time`       --BIGINT COMMENT '持续时间毫秒'
    from ods_log_inc
    where dt = '2022-06-08'
    and page is not null;
    set hive.cbo.enable=true;
    
    -- 用户域用户注册事务事实表
        -- 用户域
        -- 用户注册成功
            -- 用户(会员)+ 时间
            -- user_info(insert)
        -- 事务事实表
        -- 建表语句
    DROP TABLE IF EXISTS dwd_user_register_inc;
    CREATE EXTERNAL TABLE dwd_user_register_inc
    (
        `user_id`          STRING COMMENT '用户ID',
        `date_id`          STRING COMMENT '日期ID',
        `create_time`     STRING COMMENT '注册时间',
        `channel`          STRING COMMENT '应用下载渠道',
        `province_id`     STRING COMMENT '省份ID',
        `version_code`    STRING COMMENT '应用版本',
        `mid_id`           STRING COMMENT '设备ID',
        `brand`            STRING COMMENT '设备品牌',
        `model`            STRING COMMENT '设备型号',
        `operate_system` STRING COMMENT '设备操作系统'
    ) COMMENT '用户域用户注册事务事实表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dwd/dwd_user_register_inc/'
        TBLPROPERTIES ("orc.compress" = "snappy");
    
    -- 数据装载
        -- 页面浏览日志:离开页面的时候
    -- insert overwrite table dwd_user_register_inc partition (dt='2022-06-08')
    -- select
    --     common.uid `user_id`         ,-- STRING COMMENT '用户ID',
    --     date_format(from_utc_timestamp(ts, 'GMT+8'), 'yyyy-MM-dd') `date_id`         ,-- STRING COMMENT '日期ID',
    --     date_format(from_utc_timestamp(ts, 'GMT+8'), 'yyyy-MM-dd HH:mm:ss') `create_time`     ,--STRING COMMENT '注册时间',
    --     common.ch `channel`         ,-- STRING COMMENT '应用下载渠道',
    --     common.ar `province_id`     ,--STRING COMMENT '省份ID',
    --     common.vc `version_code`    ,--STRING COMMENT '应用版本',
    --     common.mid `mid_id`          ,-- STRING COMMENT '设备ID',
    --     common.ba `brand`           ,-- STRING COMMENT '设备品牌',
    --     common.md `model`           ,-- STRING COMMENT '设备型号',
    --     common.os `operate_system`   --STRING COMMENT '设备操作系统'
    -- from ods_log_inc
    -- where dt = '2022-06-08'
    -- and page.page_id = 'register'
    -- and common.uid is not null;
    
    -- 首日
    insert overwrite table dwd_user_register_inc partition (dt)
    select
        `user_id`        ,--  STRING COMMENT '用户ID',
        `date_id`        ,--  STRING COMMENT '日期ID',
        `create_time`    ,-- STRING COMMENT '注册时间',
        `channel`        ,--  STRING COMMENT '应用下载渠道',
        `province_id`    ,-- STRING COMMENT '省份ID',
        `version_code`   ,-- STRING COMMENT '应用版本',
        `mid_id`         ,--  STRING COMMENT '设备ID',
        `brand`          ,--  STRING COMMENT '设备品牌',
        `model`          ,--  STRING COMMENT '设备型号',
        `operate_system` ,--STRING COMMENT '设备操作系统'
        date_id
    from (
        select
            data.id,
            date_format(data.create_time, 'yyyy-MM-dd') date_id,
            data.create_time
        from ods_user_info_inc
        where dt = '2022-06-08'
        and type = 'bootstrap-insert'
    ) ui
    left join (
        select
            common.uid `user_id`         ,-- STRING COMMENT '用户ID',
            common.ch `channel`         ,-- STRING COMMENT '应用下载渠道',
            common.ar `province_id`     ,--STRING COMMENT '省份ID',
            common.vc `version_code`    ,--STRING COMMENT '应用版本',
            common.mid `mid_id`          ,-- STRING COMMENT '设备ID',
            common.ba `brand`           ,-- STRING COMMENT '设备品牌',
            common.md `model`           ,-- STRING COMMENT '设备型号',
            common.os `operate_system`   --STRING COMMENT '设备操作系统'
        from ods_log_inc
        where dt = '2022-06-08'
        and page.page_id = 'register'
        and common.uid is not null
    ) log on ui.id = log.user_id;
    
    -- 每日
    insert overwrite table dwd_user_register_inc partition (dt = '2022-06-09')
    select
        `user_id`        ,--  STRING COMMENT '用户ID',
        `date_id`        ,--  STRING COMMENT '日期ID',
        `create_time`    ,-- STRING COMMENT '注册时间',
        `channel`        ,--  STRING COMMENT '应用下载渠道',
        `province_id`    ,-- STRING COMMENT '省份ID',
        `version_code`   ,-- STRING COMMENT '应用版本',
        `mid_id`         ,--  STRING COMMENT '设备ID',
        `brand`          ,--  STRING COMMENT '设备品牌',
        `model`          ,--  STRING COMMENT '设备型号',
        `operate_system`  --STRING COMMENT '设备操作系统'
    from (
        select
            data.id,
            date_format(data.create_time, 'yyyy-MM-dd') date_id,
            data.create_time
        from ods_user_info_inc
        where dt = '2022-06-09'
        and type = 'insert'
    ) ui
    left join (  -- 日志有丢失
        select
            common.uid `user_id`         ,-- STRING COMMENT '用户ID',
            common.ch `channel`         ,-- STRING COMMENT '应用下载渠道',
            common.ar `province_id`     ,--STRING COMMENT '省份ID',
            common.vc `version_code`    ,--STRING COMMENT '应用版本',
            common.mid `mid_id`          ,-- STRING COMMENT '设备ID',
            common.ba `brand`           ,-- STRING COMMENT '设备品牌',
            common.md `model`           ,-- STRING COMMENT '设备型号',
            common.os `operate_system`   --STRING COMMENT '设备操作系统'
        from ods_log_inc
        where dt = '2022-06-09'
        and page.page_id = 'register'
        and common.uid is not null
    ) log on ui.id = log.user_id;
    
    -- 用户域用户登录事务事实表
        -- 用户域
        -- 用户登录成功
            -- 用户 + 时间 + (次数)
        -- 事务事实表
        -- 建表语句
    DROP TABLE IF EXISTS dwd_user_login_inc;
    CREATE EXTERNAL TABLE dwd_user_login_inc
    (
        `user_id`         STRING COMMENT '用户ID',
        `date_id`         STRING COMMENT '日期ID',
        `login_time`     STRING COMMENT '登录时间',
        `channel`         STRING COMMENT '应用下载渠道',
        `province_id`    STRING COMMENT '省份ID',
        `version_code`   STRING COMMENT '应用版本',
        `mid_id`          STRING COMMENT '设备ID',
        `brand`           STRING COMMENT '设备品牌',
        `model`           STRING COMMENT '设备型号',
        `operate_system` STRING COMMENT '设备操作系统'
    ) COMMENT '用户域用户登录事务事实表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dwd/dwd_user_login_inc/'
        TBLPROPERTIES ("orc.compress" = "snappy");
    
    -- 数据装载
    -- 会话内第一个uid不为null的页面就对应一次登录操作
    insert overwrite table dwd_user_login_inc partition (dt = '2022-06-08')
    select
        `user_id`         ,--STRING COMMENT '用户ID',
        date_format(from_utc_timestamp(ts, 'GMT+8'), 'yyyy-MM-dd') `date_id`         ,--STRING COMMENT '日期ID',
        date_format(from_utc_timestamp(ts, 'GMT+8'), 'yyyy-MM-dd HH:mm:ss') `login_time`      ,--STRING COMMENT '登录时间',
        `channel`         ,--STRING COMMENT '应用下载渠道',
        `province_id`     ,--STRING COMMENT '省份ID',
        `version_code`    ,--STRING COMMENT '应用版本',
        `mid_id`          ,--STRING COMMENT '设备ID',
        `brand`           ,--STRING COMMENT '设备品牌',
        `model`           ,--STRING COMMENT '设备型号',
        `operate_system`   --STRING COMMENT '设备操作系统'
    from (
        select
            ts,
            common.uid `user_id`         ,-- STRING COMMENT '用户ID',
            common.ch `channel`         ,-- STRING COMMENT '应用下载渠道',
            common.ar `province_id`     ,--STRING COMMENT '省份ID',
            common.vc `version_code`    ,--STRING COMMENT '应用版本',
            common.mid `mid_id`          ,-- STRING COMMENT '设备ID',
            common.ba `brand`           ,-- STRING COMMENT '设备品牌',
            common.md `model`           ,-- STRING COMMENT '设备型号',
            common.os `operate_system`  ,--STRING COMMENT '设备操作系统'
            row_number() over (partition by common.sid order by ts) rn  -- 开窗
        from ods_log_inc
        where dt = '2022-06-08'
        and page is not null
        and common.uid is not null
    ) t where rn = 1;
    
  • DWS层

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
    665
    666
    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    680
    681
    682
    683
    684
    685
    686
    687
    688
    689
    690
    691
    692
    693
    694
    695
    696
    697
    698
    699
    700
    701
    702
    703
    704
    705
    706
    707
    708
    709
    710
    711
    712
    713
    714
    715
    716
    717
    718
    719
    720
    721
    722
    723
    724
    725
    726
    727
    728
    729
    730
    731
    732
    733
    734
    735
    736
    737
    738
    739
    740
    741
    742
    743
    744
    745
    746
    747
    748
    749
    750
    751
    752
    753
    754
    755
    756
    757
    758
    759
    760
    761
    762
    763
    764
    765
    766
    767
    768
    769
    770
    771
    772
    773
    774
    775
    776
    777
    778
    779
    780
    781
    782
    783
    784
    785
    786
    787
    788
    789
    790
    791
    792
    793
    794
    795
    796
    797
    798
    799
    800
    801
    802
    803
    804
    805
    806
    807
    808
    809
    810
    811
    812
    813
    814
    815
    816
    817
    818
    819
    820
    821
    822
    823
    824
    825
    826
    827
    828
    829
    830
    831
    832
    833
    834
    835
    836
    837
    838
    839
    840
    841
    842
    843
    844
    845
    846
    847
    848
    849
    850
    851
    852
    853
    854
    855
    856
    857
    858
    859
    860
    861
    862
    863
    864
    865
    866
    867
    868
    869
    870
    871
    872
    873
    874
    875
    876
    877
    878
    879
    880
    881
    882
    883
    884
    885
    886
    887
    888
    889
    890
    891
    892
    893
    894
    895
    896
    897
    898
    899
    900
    901
    902
    903
    904
    905
    906
    907
    908
    909
    910
    911
    912
    913
    914
    915
    916
    917
    918
    919
    920
    921
    922
    923
    924
    925
    926
    927
    928
    929
    930
    931
    932
    933
    934
    935
    936
    937
    938
    939
    940
    941
    942
    943
    944
    945
    946
    947
    948
    949
    950
    951
    952
    953
    954
    955
    956
    957
    958
    959
    960
    961
    962
    963
    964
    965
    966
    967
    968
    969
    970
    971
    972
    973
    974
    975
    976
    977
    978
    979
    980
    981
    982
    983
    984
    985
    986
    987
    988
    989
    990
    991
    992
    993
    994
    
    -- DWS
        -- Data Warehouse Summary
            -- Data Warehouse : 数据仓库
            -- Summary : 汇总(预聚合)
                -- 用于将DIM、DWD的数据进行提前统计,将统计结果保存到当前的表中(中间计算表)
                -- 当前的表不是最终的统计结果表
                    -- 数据量可能比较多,表的设计中应该添加分区
                    -- 当前表需要进一步聚合处理,所以表的设计中应该是列式存储,采用snappy压缩
                -- 表的分类:根据数据范围进行分类
                    -- 1d:1天数据的统计
                        -- 数据来源为DIM、DWD
                    -- nd:N天数据的统计(不包括 1)
                        -- 数据来源必须为1d表
                    -- td:所有数据的统计
                        -- 数据来源可以为1d表
                        -- 数据来源可以为DIM、DWD
            -- 表的设计
                -- 参考ADS层表的设计
                    -- 指标体系:
                        -- 原子指标(拆分指标)
                            -- 行为、统计字段、统计逻辑
                        -- 派生指标(增加条件)
                            -- 统计周期(数据范围)、业务限定(筛选条件)、统计粒度(分组维度)
                        -- 衍生指标(比率、比例)
                -- 表名
                    -- 分层标记 (dws_) + 数据域 + 统计粒度 + 业务过程 + 统计周期(1d/nd/td)
                        -- 指标:客户想要的一个统计结果(数值)
                            -- 业务过程相同:数据来源相同
                            -- 统计周期相同:数据范围相同
                            -- 统计粒度相同:数据含义相同
    
    -- 交易域用户商品粒度订单最近1日汇总表
        -- 交易域
        -- 用户商品粒度
            -- user + sku
        -- 订单
            -- 下单(行为)
        -- 最近1日汇总表
            -- 数据范围
    
    -- 建表语句
    DROP TABLE IF EXISTS dws_trade_user_sku_order_1d;
    CREATE EXTERNAL TABLE dws_trade_user_sku_order_1d
    (
        `user_id`                   STRING COMMENT '用户ID',
        `sku_id`                    STRING COMMENT 'SKU_ID',
        `sku_name`                  STRING COMMENT 'SKU名称',
        `category1_id`              STRING COMMENT '一级品类ID',
        `category1_name`            STRING COMMENT '一级品类名称',
        `category2_id`              STRING COMMENT '二级品类ID',
        `category2_name`            STRING COMMENT '二级品类名称',
        `category3_id`              STRING COMMENT '三级品类ID',
        `category3_name`            STRING COMMENT '三级品类名称',
        `tm_id`                      STRING COMMENT '品牌ID',
        `tm_name`                    STRING COMMENT '品牌名称',
        `order_count_1d`            BIGINT COMMENT '最近1日下单次数',
        `order_num_1d`              BIGINT COMMENT '最近1日下单件数',
        `order_original_amount_1d`  DECIMAL(16, 2) COMMENT '最近1日下单原始金额',
        `activity_reduce_amount_1d` DECIMAL(16, 2) COMMENT '最近1日活动优惠金额',
        `coupon_reduce_amount_1d`   DECIMAL(16, 2) COMMENT '最近1日优惠券优惠金额',
        `order_total_amount_1d`     DECIMAL(16, 2) COMMENT '最近1日下单最终金额'
    ) COMMENT '交易域用户商品粒度订单最近1日汇总表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_trade_user_sku_order_1d'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- 数据装载
        -- 1d表存储的数据为1天的行为数据的统计结果,存放到这一天的分区中
        -- dwd的数据其实是包含历史行为数据(7,6,5,4),历史行为也需要统计
        -- 1d表的数据装载分为首日装载和每日装载
            -- 首日装载:包含历史数据
            -- 每日装载:包含当天数据
    
    -- 首日数据装载
    insert overwrite table dws_trade_user_sku_order_1d partition (dt)
    select
        `user_id`                   ,--STRING COMMENT '用户ID',
        `sku_id`                    ,--STRING COMMENT 'SKU_ID',
        `sku_name`                  ,--STRING COMMENT 'SKU名称',
        `category1_id`              ,--STRING COMMENT '一级品类ID',
        `category1_name`            ,--STRING COMMENT '一级品类名称',
        `category2_id`              ,--STRING COMMENT '二级品类ID',
        `category2_name`            ,--STRING COMMENT '二级品类名称',
        `category3_id`              ,--STRING COMMENT '三级品类ID',
        `category3_name`            ,--STRING COMMENT '三级品类名称',
        `tm_id`                     ,-- STRING COMMENT '品牌ID',
        `tm_name`                   ,-- STRING COMMENT '品牌名称',
        count(distinct order_id) `order_count_1d`            ,--BIGINT COMMENT '最近1日下单次数',
        sum(sku_num) `order_num_1d`              ,--BIGINT COMMENT '最近1日下单件数',
        sum(split_original_amount) `order_original_amount_1d`  ,--DECIMAL(16, 2) COMMENT '最近1日下单原始金额',
        sum(split_activity_amount) `activity_reduce_amount_1d` ,--DECIMAL(16, 2) COMMENT '最近1日活动优惠金额',
        sum(split_coupon_amount) `coupon_reduce_amount_1d`   ,--DECIMAL(16, 2) COMMENT '最近1日优惠券优惠金额',
        sum(split_total_amount) `order_total_amount_1d`      ,--DECIMAL(16, 2) COMMENT '最近1日下单最终金额'
        dt
    from  (
        select
            `user_id`                   ,--STRING COMMENT '用户ID',
            `sku_id`                    ,--STRING COMMENT 'SKU_ID'
            `order_id`,
            `sku_num`,
            split_original_amount,
            split_activity_amount,
            split_coupon_amount,
            split_total_amount,
            dt
        from dwd_trade_order_detail_inc
    ) od
    left join (
        select
            `id`,
            `sku_name`                  ,--STRING COMMENT 'SKU名称',
            `category1_id`              ,--STRING COMMENT '一级品类ID',
            `category1_name`            ,--STRING COMMENT '一级品类名称',
            `category2_id`              ,--STRING COMMENT '二级品类ID',
            `category2_name`            ,--STRING COMMENT '二级品类名称',
            `category3_id`              ,--STRING COMMENT '三级品类ID',
            `category3_name`            ,--STRING COMMENT '三级品类名称',
            `tm_id`                     ,-- STRING COMMENT '品牌ID',
            `tm_name`                    -- STRING COMMENT '品牌名称',
        from dim_sku_full
        where dt = '2022-06-08'
    ) sku on od.sku_id = sku.id
    group by `user_id`,
             `sku_id`,
             `sku_name`,
             `category1_id`,
             `category1_name`,
             `category2_id`,
             `category2_name`,
             `category3_id`,
             `category3_name`,
             `tm_id`,
             `tm_name`,
             `dt`;
    
    -- 每日数据装载
    insert overwrite table dws_trade_user_sku_order_1d partition (dt = '2022-06-09')
    select
        `user_id`                   ,--STRING COMMENT '用户ID',
        `sku_id`                    ,--STRING COMMENT 'SKU_ID',
        `sku_name`                  ,--STRING COMMENT 'SKU名称',
        `category1_id`              ,--STRING COMMENT '一级品类ID',
        `category1_name`            ,--STRING COMMENT '一级品类名称',
        `category2_id`              ,--STRING COMMENT '二级品类ID',
        `category2_name`            ,--STRING COMMENT '二级品类名称',
        `category3_id`              ,--STRING COMMENT '三级品类ID',
        `category3_name`            ,--STRING COMMENT '三级品类名称',
        `tm_id`                     ,-- STRING COMMENT '品牌ID',
        `tm_name`                   ,-- STRING COMMENT '品牌名称',
        count(distinct order_id) `order_count_1d`            ,--BIGINT COMMENT '最近1日下单次数',
        sum(sku_num) `order_num_1d`              ,--BIGINT COMMENT '最近1日下单件数',
        sum(split_original_amount) `order_original_amount_1d`  ,--DECIMAL(16, 2) COMMENT '最近1日下单原始金额',
        sum(split_activity_amount) `activity_reduce_amount_1d` ,--DECIMAL(16, 2) COMMENT '最近1日活动优惠金额',
        sum(split_coupon_amount) `coupon_reduce_amount_1d`   ,--DECIMAL(16, 2) COMMENT '最近1日优惠券优惠金额',
        sum(split_total_amount) `order_total_amount_1d`      --DECIMAL(16, 2) COMMENT '最近1日下单最终金额'
    from  (
        select
            `user_id`                   ,--STRING COMMENT '用户ID',
            `sku_id`                    ,--STRING COMMENT 'SKU_ID'
            `order_id`,
            `sku_num`,
            split_original_amount,
            split_activity_amount,
            split_coupon_amount,
            split_total_amount
        from dwd_trade_order_detail_inc
        where dt = '2022-06-09'
    ) od
    left join (
        select
            `id`,
            `sku_name`                  ,--STRING COMMENT 'SKU名称',
            `category1_id`              ,--STRING COMMENT '一级品类ID',
            `category1_name`            ,--STRING COMMENT '一级品类名称',
            `category2_id`              ,--STRING COMMENT '二级品类ID',
            `category2_name`            ,--STRING COMMENT '二级品类名称',
            `category3_id`              ,--STRING COMMENT '三级品类ID',
            `category3_name`            ,--STRING COMMENT '三级品类名称',
            `tm_id`                     ,-- STRING COMMENT '品牌ID',
            `tm_name`                    -- STRING COMMENT '品牌名称',
        from dim_sku_full
        where dt = '2022-06-09'
    ) sku on od.sku_id = sku.id
    group by `user_id`,
             `sku_id`,
             `sku_name`,
             `category1_id`,
             `category1_name`,
             `category2_id`,
             `category2_name`,
             `category3_id`,
             `category3_name`,
             `tm_id`,
             `tm_name`;
    
    -- 思路:补全数据 => 统计(效率低、逻辑简单:缺什么补什么)
        --  统计 => 补全数据(效率高,连接之前先减少数据)
                -- 统计结果和不全数据没有关系
    
    -- 交易域用户商品粒度订单最近n日汇总表
        -- 交易域
        -- 用户商品粒度
            -- user + sku
        -- 订单
            -- 下单:order
        -- 最近n日汇总表
            -- nd
                -- 表设计:参考1d表
                -- 数据来源:1d表
    
    -- 建表语句
    DROP TABLE IF EXISTS dws_trade_user_sku_order_nd;
    CREATE EXTERNAL TABLE dws_trade_user_sku_order_nd
    (
        `user_id`                   STRING COMMENT '用户ID',
        `sku_id`                    STRING COMMENT 'SKU_ID',
        `sku_name`                  STRING COMMENT 'SKU名称',
        `category1_id`              STRING COMMENT '一级品类ID',
        `category1_name`            STRING COMMENT '一级品类名称',
        `category2_id`              STRING COMMENT '二级品类ID',
        `category2_name`            STRING COMMENT '二级品类名称',
        `category3_id`              STRING COMMENT '三级品类ID',
        `category3_name`            STRING COMMENT '三级品类名称',
        `tm_id`                      STRING COMMENT '品牌ID',
        `tm_name`                    STRING COMMENT '品牌名称',
        `order_count_7d`            BIGINT COMMENT '最近1日下单次数',
        `order_num_7d`              BIGINT COMMENT '最近1日下单件数',
        `order_original_amount_7d`  DECIMAL(16, 2) COMMENT '最近1日下单原始金额',
        `activity_reduce_amount_7d` DECIMAL(16, 2) COMMENT '最近1日活动优惠金额',
        `coupon_reduce_amount_7d`   DECIMAL(16, 2) COMMENT '最近1日优惠券优惠金额',
        `order_total_amount_7d`     DECIMAL(16, 2) COMMENT '最近1日下单最终金额',
        `order_count_30d`            BIGINT COMMENT '最近1日下单次数',
        `order_num_30d`              BIGINT COMMENT '最近1日下单件数',
        `order_original_amount_30d`  DECIMAL(16, 2) COMMENT '最近1日下单原始金额',
        `activity_reduce_amount_30d` DECIMAL(16, 2) COMMENT '最近1日活动优惠金额',
        `coupon_reduce_amount_30d`   DECIMAL(16, 2) COMMENT '最近1日优惠券优惠金额',
        `order_total_amount_30d`     DECIMAL(16, 2) COMMENT '最近1日下单最终金额'
    ) COMMENT '交易域用户商品粒度订单最近n日汇总表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_trade_user_sku_order_nd'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    
    -- nd表的数据装载基本思路
        -- 1. 读取最大范围i的数据
            -- 30d
        -- 2. 同时计算不同时间范围的数据
            -- sum(if):有条件求和
    insert overwrite table dws_trade_user_sku_order_nd partition (dt = '2022-06-08')
    select
        `user_id`                   ,--STRING COMMENT '用户ID',
        `sku_id`                    ,--STRING COMMENT 'SKU_ID',
        `sku_name`                  ,--STRING COMMENT 'SKU名称',
        `category1_id`              ,--STRING COMMENT '一级品类ID',
        `category1_name`            ,--STRING COMMENT '一级品类名称',
        `category2_id`              ,--STRING COMMENT '二级品类ID',
        `category2_name`            ,--STRING COMMENT '二级品类名称',
        `category3_id`              ,--STRING COMMENT '三级品类ID',
        `category3_name`            ,--STRING COMMENT '三级品类名称',
        `tm_id`                     ,-- STRING COMMENT '品牌ID',
        `tm_name`                   ,-- STRING COMMENT '品牌名称',
    
        sum(if (dt >= date_sub('2022-06-08', 6), order_count_1d, 0)),
        sum(if (dt >= date_sub('2022-06-08', 6), order_num_1d, 0)),
        sum(if (dt >= date_sub('2022-06-08', 6), order_original_amount_1d, 0)),
        sum(if (dt >= date_sub('2022-06-08', 6), activity_reduce_amount_1d, 0)),
        sum(if (dt >= date_sub('2022-06-08', 6), coupon_reduce_amount_1d, 0)),
        sum(if (dt >= date_sub('2022-06-08', 6), order_total_amount_1d, 0)),
    
        sum(order_count_1d),
        sum(order_num_1d),
        sum(order_original_amount_1d),
        sum(activity_reduce_amount_1d),
        sum(coupon_reduce_amount_1d),
        sum(order_total_amount_1d)
    from dws_trade_user_sku_order_1d
    where dt >= date_sub('2022-06-08', 29) and dt <= '2022-06-08'
    group by `user_id`,
             `sku_id`,
             `sku_name`,
             `category1_id`,
             `category1_name`,
             `category2_id`,
             `category2_name`,
             `category3_id`,
             `category3_name`,
             `tm_id`, `tm_name`;
    
    -- 1d:交易域用户粒度订单最近1日汇总表
        -- 交易域
        -- 用户粒度
            -- user
        -- 订单
            -- 下单:
        -- 最近1日汇总表
            -- 1d
    
    -- 建表语句
    DROP TABLE IF EXISTS dws_trade_user_order_1d;
    CREATE EXTERNAL TABLE dws_trade_user_order_1d
    (
        `user_id`                   STRING COMMENT '用户ID',
        `order_count_1d`            BIGINT COMMENT '最近1日下单次数',
        `order_num_1d`              BIGINT COMMENT '最近1日下单商品件数',
        `order_original_amount_1d`  DECIMAL(16, 2) COMMENT '最近1日下单原始金额',
        `activity_reduce_amount_1d` DECIMAL(16, 2) COMMENT '最近1日下单活动优惠金额',
        `coupon_reduce_amount_1d`   DECIMAL(16, 2) COMMENT '最近1日下单优惠券优惠金额',
        `order_total_amount_1d`     DECIMAL(16, 2) COMMENT '最近1日下单最终金额'
    ) COMMENT '交易域用户粒度订单最近1日汇总表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_trade_user_order_1d'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- 首日数据装载
    insert overwrite table dws_trade_user_order_1d partition (dt)
    select
        user_id,
        count(distinct order_id),
        sum(sku_num),
        sum(split_original_amount),
        sum(split_activity_amount),
        sum(split_coupon_amount),
        sum(split_total_amount),
        dt
    from dwd_trade_order_detail_inc
    where dt = '2022-06-08'
    group by user_id, dt;
    
    -- 每日数据装载
    insert overwrite table dws_trade_user_order_1d partition (dt = '2022-06-09')
    select
        user_id,
        count(distinct order_id),
        sum(sku_num),
        sum(split_original_amount),
        sum(split_activity_amount),
        sum(split_coupon_amount),
        sum(split_total_amount)
    from dwd_trade_order_detail_inc
    where dt = '2022-06-09'
    group by user_id;
    
    -- 粒度的变化问题
        -- DWS层的表不是最终的表,还需要进一步计算
            -- dws:user + sku (tm)
            -- ads:tm
    
    -- 三种情况
    --------------------------------------------------------------------------
        -- dws:user + sku
        -- ads:sku
        -- 当前的统计粒度减少,并且就是对减少的那个粒度做统计,此时无需判重
        -- 当前的统计粒度减少,对其他字段进行进一步统计,需要聚合数据
    ---------------------------------------------------------------------------
        -- dws:user + sku
        -- ads:tm
        -- 当前的统计粒度减少,此时必须判重
        -- 当前的统计粒度减少,对其他字段进行进一步统计,需要聚合数据
    ---------------------------------------------------------------------------
        -- dws:user + sku
        -- ads:user + sku
        -- 粒度没有变化的情况下,可以直接将中间表的数据获取后使用
    
    -- 交易域用户粒度订单历史至今汇总表
        -- 交易域
        -- 用户粒度
        -- 订单
            -- 下单
        -- 历史至今汇总表
    
    -- 建表语句
    DROP TABLE IF EXISTS dws_trade_user_order_td;
    CREATE EXTERNAL TABLE dws_trade_user_order_td
    (
        `user_id`                   STRING COMMENT '用户ID',
        `order_date_first`          STRING COMMENT '历史至今首次下单日期',
        `order_date_last`           STRING COMMENT '历史至今末次下单日期',
        `order_count_td`            BIGINT COMMENT '历史至今下单次数',
        `order_num_td`              BIGINT COMMENT '历史至今购买商品件数',
        `original_amount_td`        DECIMAL(16, 2) COMMENT '历史至今下单原始金额',
        `activity_reduce_amount_td` DECIMAL(16, 2) COMMENT '历史至今下单活动优惠金额',
        `coupon_reduce_amount_td`   DECIMAL(16, 2) COMMENT '历史至今下单优惠券优惠金额',
        `total_amount_td`           DECIMAL(16, 2) COMMENT '历史至今下单最终金额'
    ) COMMENT '交易域用户粒度订单历史至今汇总表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_trade_user_order_td'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- td表的数据装载一般为了考虑效率,会分成首日装载和每日装载
        -- 首日装载:直接获取所有的数据做聚合
        -- 每日装载:装载的数据只比前一天多了一天的数据,而前一天的数据已经统计过了,所以存在重复计算
            -- 改善装载的思路:获取昨天的统计结果 + 今天新的数据 => 做进一步的聚合
    -- 首日数据装载
    insert overwrite table dws_trade_user_order_td partition (dt = '2022-06-08')
    select
        user_id,
        min(dt) order_date_first,
        max(dt) order_date_last,
        sum(order_count_1d),
        sum(order_num_1d),
        sum(order_original_amount_1d),
        sum(activity_reduce_amount_1d),
        sum(coupon_reduce_amount_1d),
        sum(order_total_amount_1d)
    from dws_trade_user_order_1d
    group by user_id;
    -- 每日数据装载
    insert overwrite table dws_trade_user_order_td partition (dt = '2022-06-09')
    select
        user_id,
        min(order_date_first),
        max(order_date_last),
        sum(order_count_td),
        sum(order_num_td),
        sum(original_amount_td),
        sum(activity_reduce_amount_td),
        sum(coupon_reduce_amount_td),
        sum(total_amount_td)
    from (
        select
            `user_id`                   ,--STRING COMMENT '用户ID',
            `order_date_first`          ,--STRING COMMENT '历史至今首次下单日期',
            `order_date_last`           ,--STRING COMMENT '历史至今末次下单日期',
            `order_count_td`            ,--BIGINT COMMENT '历史至今下单次数',
            `order_num_td`              ,--BIGINT COMMENT '历史至今购买商品件数',
            `original_amount_td`        ,--DECIMAL(16, 2) COMMENT '历史至今下单原始金额',
            `activity_reduce_amount_td` ,--DECIMAL(16, 2) COMMENT '历史至今下单活动优惠金额',
            `coupon_reduce_amount_td`   ,--DECIMAL(16, 2) COMMENT '历史至今下单优惠券优惠金额',
            `total_amount_td`            --DECIMAL(16, 2) COMMENT '历史至今下单最终金额'
        from dws_trade_user_order_td
        where dt = date_sub('2022-06-09', 1)
        union all
        select
            `user_id`                   ,--STRING COMMENT '用户ID',
            '2022-06-09'           ,--STRING COMMENT '历史至今首次下单日期',
            '2022-06-09'           ,--STRING COMMENT '历史至今末次下单日期',
            `order_count_1d`            ,--BIGINT COMMENT '历史至今下单次数',
            `order_num_1d`              ,--BIGINT COMMENT '历史至今购买商品件数',
            `order_original_amount_1d`        ,--DECIMAL(16, 2) COMMENT '历史至今下单原始金额',
            `activity_reduce_amount_1d` ,--DECIMAL(16, 2) COMMENT '历史至今下单活动优惠金额',
            `coupon_reduce_amount_1d`   ,--DECIMAL(16, 2) COMMENT '历史至今下单优惠券优惠金额',
            `order_total_amount_1d`            --DECIMAL(16, 2) COMMENT '历史至今下单最终金额'
        from dws_trade_user_order_1d
        where dt = '2022-06-09'
    ) t group by user_id
    
    -- 交易域用户粒度加购最近1日汇总表
    DROP TABLE IF EXISTS dws_trade_user_cart_add_1d;
    CREATE EXTERNAL TABLE dws_trade_user_cart_add_1d
    (
        `user_id`           STRING COMMENT '用户ID',
        `cart_add_count_1d` BIGINT COMMENT '最近1日加购次数',
        `cart_add_num_1d`   BIGINT COMMENT '最近1日加购商品件数'
    ) COMMENT '交易域用户粒度加购最近1日汇总表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_trade_user_cart_add_1d'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- 1d表首日包含历史数据
        -- user + sku
    insert overwrite table dws_trade_user_cart_add_1d partition (dt)
    select
        user_id,
        count(*),
        sum(sku_num),
        dt
    from dwd_trade_cart_add_inc
    group by dt, user_id;
    
    -- 每日数据装载
    insert overwrite table dws_trade_user_cart_add_1d partition (dt = '2022-06-09')
    select
        user_id,
        count(*),
        sum(sku_num)
    from dwd_trade_cart_add_inc
    where dt = '2022-06-09'
    group by user_id;
    
    -- 交易域用户粒度支付最近1日汇总表
    DROP TABLE IF EXISTS dws_trade_user_payment_1d;
    CREATE EXTERNAL TABLE dws_trade_user_payment_1d
    (
        `user_id`           STRING COMMENT '用户ID',
        `payment_count_1d`  BIGINT COMMENT '最近1日支付次数',
        `payment_num_1d`    BIGINT COMMENT '最近1日支付商品件数',
        `payment_amount_1d` DECIMAL(16, 2) COMMENT '最近1日支付金额'
    ) COMMENT '交易域用户粒度支付最近1日汇总表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_trade_user_payment_1d'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    -- 首日数据装载
    -- 一次支付三个商品,就有三条数据
    insert overwrite table dws_trade_user_payment_1d partition (dt)
    select
        user_id,
        count(distinct order_id),
        sum(sku_num),
        sum(split_payment_amount),
        dt
    from dwd_trade_pay_detail_suc_inc
    group by user_id, dt;
    
    -- 每日数据装载
    insert overwrite table dws_trade_user_payment_1d partition (dt = '2022-06-09')
    select
        user_id,
        count(distinct order_id),
        sum(sku_num),
        sum(split_payment_amount)
    from dwd_trade_pay_detail_suc_inc
    where dt = '2022-06-09'
    group by user_id;
    
    -- 交易域省份粒度订单最近1日汇总表
    DROP TABLE IF EXISTS dws_trade_province_order_1d;
    CREATE EXTERNAL TABLE dws_trade_province_order_1d
    (
        `province_id`               STRING COMMENT '省份ID',
        `province_name`             STRING COMMENT '省份名称',
        `area_code`                 STRING COMMENT '地区编码',
        `iso_code`                  STRING COMMENT '旧版国际标准地区编码',
        `iso_3166_2`                STRING COMMENT '新版国际标准地区编码',
        `order_count_1d`            BIGINT COMMENT '最近1日下单次数',
        `order_original_amount_1d`  DECIMAL(16, 2) COMMENT '最近1日下单原始金额',
        `activity_reduce_amount_1d` DECIMAL(16, 2) COMMENT '最近1日下单活动优惠金额',
        `coupon_reduce_amount_1d`   DECIMAL(16, 2) COMMENT '最近1日下单优惠券优惠金额',
        `order_total_amount_1d`     DECIMAL(16, 2) COMMENT '最近1日下单最终金额'
    ) COMMENT '交易域省份粒度订单最近1日汇总表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_trade_province_order_1d'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- 首日数据装载
    insert overwrite table dws_trade_province_order_1d partition (dt)
    select
        `province_id`               ,--STRING COMMENT '省份ID',
        `province_name`             ,--STRING COMMENT '省份名称',
        `area_code`                 ,--STRING COMMENT '地区编码',
        `iso_code`                  ,--STRING COMMENT '旧版国际标准地区编码',
        `iso_3166_2`                ,--STRING COMMENT '新版国际标准地区编码',
        `order_count_1d`            ,--BIGINT COMMENT '最近1日下单次数',
        `order_original_amount_1d`  ,--DECIMAL(16, 2) COMMENT '最近1日下单原始金额',
        `activity_reduce_amount_1d` ,--DECIMAL(16, 2) COMMENT '最近1日下单活动优惠金额',
        `coupon_reduce_amount_1d`   ,--DECIMAL(16, 2) COMMENT '最近1日下单优惠券优惠金额',
        `order_total_amount_1d`     ,--DECIMAL(16, 2) COMMENT '最近1日下单最终金额'
        dt
    from (
        select
            province_id,
            count(distinct order_id) order_count_1d,
            sum(split_original_amount) order_original_amount_1d,
            sum(split_activity_amount) activity_reduce_amount_1d,
            sum(split_coupon_amount) coupon_reduce_amount_1d,
            sum(split_total_amount) order_total_amount_1d,
            dt
        from dwd_trade_order_detail_inc
        group by province_id, dt
    ) od
    left join (
        select
            id,
            province_name,
            area_code,
            iso_code,
            iso_3166_2
        from dim_province_full
        where dt = '2022-06-08'
    ) prv on od.province_id = prv.id;
    
    -- 每日数据装载
    insert overwrite table dws_trade_province_order_1d partition (dt = '2022-06-09')
    select
        `province_id`               ,--STRING COMMENT '省份ID',
        `province_name`             ,--STRING COMMENT '省份名称',
        `area_code`                 ,--STRING COMMENT '地区编码',
        `iso_code`                  ,--STRING COMMENT '旧版国际标准地区编码',
        `iso_3166_2`                ,--STRING COMMENT '新版国际标准地区编码',
        `order_count_1d`            ,--BIGINT COMMENT '最近1日下单次数',
        `order_original_amount_1d`  ,--DECIMAL(16, 2) COMMENT '最近1日下单原始金额',
        `activity_reduce_amount_1d` ,--DECIMAL(16, 2) COMMENT '最近1日下单活动优惠金额',
        `coupon_reduce_amount_1d`   ,--DECIMAL(16, 2) COMMENT '最近1日下单优惠券优惠金额',
        `order_total_amount_1d`      --DECIMAL(16, 2) COMMENT '最近1日下单最终金额'
    from (
        select
            province_id,
            count(distinct order_id) order_count_1d,
            sum(split_original_amount) order_original_amount_1d,
            sum(split_activity_amount) activity_reduce_amount_1d,
            sum(split_coupon_amount) coupon_reduce_amount_1d,
            sum(split_total_amount) order_total_amount_1d
        from dwd_trade_order_detail_inc
        where dt = '2022-06-09'
        group by province_id
    ) od
    left join (
        select
            id,
            province_name,
            area_code,
            iso_code,
            iso_3166_2
        from dim_province_full
        where dt = '2022-06-09'
    ) prv on od.province_id = prv.id;
    
    -- 交易域省份粒度订单最近n日汇总表
    DROP TABLE IF EXISTS dws_trade_province_order_nd;
    CREATE EXTERNAL TABLE dws_trade_province_order_nd
    (
        `province_id`                STRING COMMENT '省份ID',
        `province_name`              STRING COMMENT '省份名称',
        `area_code`                  STRING COMMENT '地区编码',
        `iso_code`                   STRING COMMENT '旧版国际标准地区编码',
        `iso_3166_2`                 STRING COMMENT '新版国际标准地区编码',
        `order_count_7d`             BIGINT COMMENT '最近7日下单次数',
        `order_original_amount_7d`   DECIMAL(16, 2) COMMENT '最近7日下单原始金额',
        `activity_reduce_amount_7d`  DECIMAL(16, 2) COMMENT '最近7日下单活动优惠金额',
        `coupon_reduce_amount_7d`    DECIMAL(16, 2) COMMENT '最近7日下单优惠券优惠金额',
        `order_total_amount_7d`      DECIMAL(16, 2) COMMENT '最近7日下单最终金额',
        `order_count_30d`            BIGINT COMMENT '最近30日下单次数',
        `order_original_amount_30d`  DECIMAL(16, 2) COMMENT '最近30日下单原始金额',
        `activity_reduce_amount_30d` DECIMAL(16, 2) COMMENT '最近30日下单活动优惠金额',
        `coupon_reduce_amount_30d`   DECIMAL(16, 2) COMMENT '最近30日下单优惠券优惠金额',
        `order_total_amount_30d`     DECIMAL(16, 2) COMMENT '最近30日下单最终金额'
    ) COMMENT '交易域省份粒度订单最近n日汇总表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_trade_province_order_nd'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    insert overwrite table dws_trade_province_order_nd partition (dt = '2022-06-08')
    select
        `province_id`                ,--STRING COMMENT '省份ID',
        `province_name`              ,--STRING COMMENT '省份名称',
        `area_code`                  ,--STRING COMMENT '地区编码',
        `iso_code`                   ,--STRING COMMENT '旧版国际标准地区编码',
        `iso_3166_2`                 ,--STRING COMMENT '新版国际标准地区编码',
        sum(if(dt >= date_sub('2022-06-08', 6), order_count_1d, 0))             ,--BIGINT COMMENT '最近7日下单次数',
        sum(if(dt >= date_sub('2022-06-08', 6), order_original_amount_1d, 0))   ,--DECIMAL(16, 2) COMMENT '最近7日下单原始金额',
        sum(if(dt >= date_sub('2022-06-08', 6), activity_reduce_amount_1d, 0))  ,--DECIMAL(16, 2) COMMENT '最近7日下单活动优惠金额',
        sum(if(dt >= date_sub('2022-06-08', 6), coupon_reduce_amount_1d, 0))    ,--DECIMAL(16, 2) COMMENT '最近7日下单优惠券优惠金额',
        sum(if(dt >= date_sub('2022-06-08', 6), order_total_amount_1d, 0))      ,--DECIMAL(16, 2) COMMENT '最近7日下单最终金额',
        sum(order_count_1d)            ,--BIGINT COMMENT '最近30日下单次数',
        sum(order_original_amount_1d)  ,--DECIMAL(16, 2) COMMENT '最近30日下单原始金额',
        sum(activity_reduce_amount_1d) ,--DECIMAL(16, 2) COMMENT '最近30日下单活动优惠金额',
        sum(coupon_reduce_amount_1d)   ,--DECIMAL(16, 2) COMMENT '最近30日下单优惠券优惠金额',
        sum(order_total_amount_1d)     --DECIMAL(16, 2) COMMENT '最近30日下单最终金额'
    from dws_trade_province_order_1d
    where dt >= date_sub('2022-06-08', 29) and dt <= '2022-06-08'
    group by `province_id`,
             `province_name`,
             `area_code`,
             `iso_code`,
             `iso_3166_2`;
    
    -- 工具域用户优惠券粒度优惠券使用(支付)最近1日汇总表
    DROP TABLE IF EXISTS dws_tool_user_coupon_coupon_used_1d;
    CREATE EXTERNAL TABLE dws_tool_user_coupon_coupon_used_1d
    (
        `user_id`          STRING COMMENT '用户ID',
        `coupon_id`        STRING COMMENT '优惠券ID',
        `coupon_name`      STRING COMMENT '优惠券名称',
        `coupon_type_code` STRING COMMENT '优惠券类型编码',
        `coupon_type_name` STRING COMMENT '优惠券类型名称',
        `benefit_rule`     STRING COMMENT '优惠规则',
        `used_count_1d`    STRING COMMENT '使用(支付)次数'
    ) COMMENT '工具域用户优惠券粒度优惠券使用(支付)最近1日汇总表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_tool_user_coupon_coupon_used_1d'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- 首日数据装载
    insert overwrite table dws_tool_user_coupon_coupon_used_1d partition (dt)
    select
        `user_id`          ,--STRING COMMENT '用户ID',
        `coupon_id`        ,--STRING COMMENT '优惠券ID',
        `coupon_name`      ,--STRING COMMENT '优惠券名称',
        `coupon_type_code` ,--STRING COMMENT '优惠券类型编码',
        `coupon_type_name` ,--STRING COMMENT '优惠券类型名称',
        `benefit_rule`     ,--STRING COMMENT '优惠规则',
        `used_count_1d`    ,--STRING COMMENT '使用(支付)次数'
        dt
    from (
        select
            user_id,
            coupon_id,
            count(*) used_count_1d,
            dt
        from dwd_tool_coupon_used_inc
        group by user_id, coupon_id, dt
    ) cu
    left join (
        select
            id,
            coupon_name,
            coupon_type_code,
            coupon_type_name,
            benefit_rule
        from dim_coupon_full
        where dt = '2022-06-08'
    ) cp on cu.coupon_id = cp.id;
    
    -- 每日数据装载
    insert overwrite table dws_tool_user_coupon_coupon_used_1d partition (dt = '2022-06-09')
    select
        `user_id`          ,--STRING COMMENT '用户ID',
        `coupon_id`        ,--STRING COMMENT '优惠券ID',
        `coupon_name`      ,--STRING COMMENT '优惠券名称',
        `coupon_type_code` ,--STRING COMMENT '优惠券类型编码',
        `coupon_type_name` ,--STRING COMMENT '优惠券类型名称',
        `benefit_rule`     ,--STRING COMMENT '优惠规则',
        `used_count_1d`     --STRING COMMENT '使用(支付)次数'
    from (
        select
            user_id,
            coupon_id,
            count(*) used_count_1d
        from dwd_tool_coupon_used_inc
        where dt = '2022-06-09'
        group by user_id, coupon_id
    ) cu
    left join (
        select
            id,
            coupon_name,
            coupon_type_code,
            coupon_type_name,
            benefit_rule
        from dim_coupon_full
        where dt = '2022-06-09'
    ) cp on cu.coupon_id = cp.id;
    
    -- 互动域商品粒度收藏商品最近1日汇总表
    DROP TABLE IF EXISTS dws_interaction_sku_favor_add_1d;
    CREATE EXTERNAL TABLE dws_interaction_sku_favor_add_1d
    (
        `sku_id`             STRING COMMENT 'SKU_ID',
        `sku_name`           STRING COMMENT 'SKU名称',
        `category1_id`       STRING COMMENT '一级品类ID',
        `category1_name`     STRING COMMENT '一级品类名称',
        `category2_id`       STRING COMMENT '二级品类ID',
        `category2_name`     STRING COMMENT '二级品类名称',
        `category3_id`       STRING COMMENT '三级品类ID',
        `category3_name`     STRING COMMENT '三级品类名称',
        `tm_id`              STRING COMMENT '品牌ID',
        `tm_name`            STRING COMMENT '品牌名称',
        `favor_add_count_1d` BIGINT COMMENT '商品被收藏次数'
    ) COMMENT '互动域商品粒度收藏商品最近1日汇总表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_interaction_sku_favor_add_1d'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- 首日数据装载
    insert overwrite table dws_interaction_sku_favor_add_1d partition (dt)
    select
        `sku_id`             ,
        `sku_name`           ,
        `category1_id`       ,
        `category1_name`     ,
        `category2_id`       ,
        `category2_name`     ,
        `category3_id`       ,
        `category3_name`     ,
        `tm_id`              ,
        `tm_name`            ,
        `favor_add_count_1d` ,
        dt
    from (
        select
            sku_id,
            count(*) favor_add_count_1d,
            dt
        from dwd_interaction_favor_add_inc
        group by sku_id, dt
    ) fa
    left join (
        select
            `id`,
            `sku_name`           ,--STRING COMMENT 'SKU名称',
            `category1_id`       ,--STRING COMMENT '一级品类ID',
            `category1_name`     ,--STRING COMMENT '一级品类名称',
            `category2_id`       ,--STRING COMMENT '二级品类ID',
            `category2_name`     ,--STRING COMMENT '二级品类名称',
            `category3_id`       ,--STRING COMMENT '三级品类ID',
            `category3_name`     ,--STRING COMMENT '三级品类名称',
            `tm_id`              ,--STRING COMMENT '品牌ID',
            `tm_name`             --STRING COMMENT '品牌名称',
        from dim_sku_full
        where dt = '2022-06-08'
    ) sku on fa.sku_id = sku.id;
    
    -- 每日数据装载
    insert overwrite table dws_interaction_sku_favor_add_1d partition (dt = '2022-06-09')
    select
        `sku_id`             ,
        `sku_name`           ,
        `category1_id`       ,
        `category1_name`     ,
        `category2_id`       ,
        `category2_name`     ,
        `category3_id`       ,
        `category3_name`     ,
        `tm_id`              ,
        `tm_name`            ,
        `favor_add_count_1d`
    from (
        select
            sku_id,
            count(*) favor_add_count_1d
        from dwd_interaction_favor_add_inc
        where dt = '2022-06-09'
        group by sku_id
    ) fa
    left join (
        select
            `id`,
            `sku_name`           ,--STRING COMMENT 'SKU名称',
            `category1_id`       ,--STRING COMMENT '一级品类ID',
            `category1_name`     ,--STRING COMMENT '一级品类名称',
            `category2_id`       ,--STRING COMMENT '二级品类ID',
            `category2_name`     ,--STRING COMMENT '二级品类名称',
            `category3_id`       ,--STRING COMMENT '三级品类ID',
            `category3_name`     ,--STRING COMMENT '三级品类名称',
            `tm_id`              ,--STRING COMMENT '品牌ID',
            `tm_name`             --STRING COMMENT '品牌名称',
        from dim_sku_full
        where dt = '2022-06-09'
    ) sku on fa.sku_id = sku.id;
    
    -- 流量域会话粒度页面浏览最近1日汇总表
    DROP TABLE IF EXISTS dws_traffic_session_page_view_1d;
    CREATE EXTERNAL TABLE dws_traffic_session_page_view_1d
    (
        `session_id`     STRING COMMENT '会话ID',
        `mid_id`         string comment '设备ID',
        `brand`          string comment '手机品牌',
        `model`          string comment '手机型号',
        `operate_system` string comment '操作系统',
        `version_code`   string comment 'APP版本号',
        `channel`        string comment '渠道',
        `during_time_1d` BIGINT COMMENT '最近1日浏览时长',
        `page_count_1d`  BIGINT COMMENT '最近1日浏览页面数'
    ) COMMENT '流量域会话粒度页面浏览最近1日汇总表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_traffic_session_page_view_1d'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- 日志无历史数据
    insert overwrite table dws_traffic_session_page_view_1d partition (dt = '2022-06-08')
    select
        session_id,
        `mid_id`         ,--string comment '设备ID',
        `brand`          ,--string comment '手机品牌',
        `model`          ,--string comment '手机型号',
        `operate_system` ,--string comment '操作系统',
        `version_code`   ,--string comment 'APP版本号',
        `channel`        ,--string comment '渠道',
        sum(during_time),
        count(page_id)
    from dwd_traffic_page_view_inc
    where dt = '2022-06-08'
    group by session_id,
             `mid_id`,
             `brand`,
             `model`,
             `operate_system`,
             `version_code`,
             `channel`;
    
    -- 流量域访客页面粒度页面浏览最近1日汇总表
    DROP TABLE IF EXISTS dws_traffic_page_visitor_page_view_1d;
    CREATE EXTERNAL TABLE dws_traffic_page_visitor_page_view_1d
    (
        `mid_id`         STRING COMMENT '访客ID',
        `brand`          string comment '手机品牌',
        `model`          string comment '手机型号',
        `operate_system` string comment '操作系统',
        `page_id`        STRING COMMENT '页面ID',
        `during_time_1d` BIGINT COMMENT '最近1日浏览时长',
        `view_count_1d`  BIGINT COMMENT '最近1日访问次数'
    ) COMMENT '流量域访客页面粒度页面浏览最近1日汇总表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_traffic_page_visitor_page_view_1d'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    insert overwrite table dws_traffic_page_visitor_page_view_1d partition (dt = '2022-06-08')
    select
        mid_id,
        brand,
        model,
        operate_system,
        page_id,
        sum(during_time),
        count(*)
    from dwd_traffic_page_view_inc
    where dt = '2022-06-08'
    group by mid_id,
             page_id,
             brand,
             model,
             operate_system;
    
    -- 用户域用户粒度登录历史至今汇总表
        -- 活跃
    DROP TABLE IF EXISTS dws_user_user_login_td;
    CREATE EXTERNAL TABLE dws_user_user_login_td
    (
        `user_id`          STRING COMMENT '用户ID',
        `login_date_last`  STRING COMMENT '历史至今末次登录日期',
        `login_date_first` STRING COMMENT '历史至今首次登录日期',
        `login_count_td`   BIGINT COMMENT '历史至今累计登录次数'
    ) COMMENT '用户域用户粒度登录历史至今汇总表'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_user_user_login_td'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- 登录信息来自于日志表,但是日志表只有8号以后的数据,没有历史数据
        -- MySQL数据库中不会保存行为数据,也就是说不会保存登录数据
        -- 折中地认为用户注册的时间就是用户首次登录时间,也就是末次登录时间
    -- 首日数据装载
    insert overwrite table dws_user_user_login_td partition (dt = '2022-06-08')
    select
        user_id,
        max(dt) login_date_last,
        min(dt) login_date_first,
        count(*) login_count_td
    from dwd_user_login_inc
    group by user_id;
    
    -- 每日数据装载
    insert overwrite table dws_user_user_login_td partition (dt = '2022-06-09')
    select
        user_id,
        max(login_date_last),
        min(login_date_first),
        sum(login_count_td)
    from (
        select
            user_id,
            login_date_last,
            login_date_first,
            login_count_td
        from dws_user_user_login_td
        where dt = date_sub('2022-06-09', 1)
        union all
        select
            user_id,
            '2022-06-09',
            '2022-06-09',
            count(*)
        from dwd_user_login_inc
        where dt = '2022-06-09'
        group by user_id
    ) t group by user_id;
    ----------------------------------------------------------------------------
    -- 首日数据使用注册数据
    -- ODS层数据是整个数据仓库的数据源,不能作为统计分析的数据源
        -- 统计分析的数据源一般是DIM、DWD层
    select
        user_id,
        max(login_date_last),
        min(login_date_first),
        sum(login_count_td)
    from (
        select
            id user_id,
            date_format(create_time, 'yyyy-MM-dd') login_date_last,
            date_format(create_time, 'yyyy-MM-dd') login_date_first,
            1 login_count_td
        from dim_user_zip
        where dt = '9999-12-31' and date_format(create_time, 'yyyy-MM-dd') != '2022-06-08'
        union all
        select
            user_id,
            '2022-06-08',
            '2022-06-08',
            count(*) login_count_td
        from dwd_user_login_inc
        where dt = '2022-06-08'
        group by user_id
    ) t group by user_id
    
  • ADS层

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
     100
     101
     102
     103
     104
     105
     106
     107
     108
     109
     110
     111
     112
     113
     114
     115
     116
     117
     118
     119
     120
     121
     122
     123
     124
     125
     126
     127
     128
     129
     130
     131
     132
     133
     134
     135
     136
     137
     138
     139
     140
     141
     142
     143
     144
     145
     146
     147
     148
     149
     150
     151
     152
     153
     154
     155
     156
     157
     158
     159
     160
     161
     162
     163
     164
     165
     166
     167
     168
     169
     170
     171
     172
     173
     174
     175
     176
     177
     178
     179
     180
     181
     182
     183
     184
     185
     186
     187
     188
     189
     190
     191
     192
     193
     194
     195
     196
     197
     198
     199
     200
     201
     202
     203
     204
     205
     206
     207
     208
     209
     210
     211
     212
     213
     214
     215
     216
     217
     218
     219
     220
     221
     222
     223
     224
     225
     226
     227
     228
     229
     230
     231
     232
     233
     234
     235
     236
     237
     238
     239
     240
     241
     242
     243
     244
     245
     246
     247
     248
     249
     250
     251
     252
     253
     254
     255
     256
     257
     258
     259
     260
     261
     262
     263
     264
     265
     266
     267
     268
     269
     270
     271
     272
     273
     274
     275
     276
     277
     278
     279
     280
     281
     282
     283
     284
     285
     286
     287
     288
     289
     290
     291
     292
     293
     294
     295
     296
     297
     298
     299
     300
     301
     302
     303
     304
     305
     306
     307
     308
     309
     310
     311
     312
     313
     314
     315
     316
     317
     318
     319
     320
     321
     322
     323
     324
     325
     326
     327
     328
     329
     330
     331
     332
     333
     334
     335
     336
     337
     338
     339
     340
     341
     342
     343
     344
     345
     346
     347
     348
     349
     350
     351
     352
     353
     354
     355
     356
     357
     358
     359
     360
     361
     362
     363
     364
     365
     366
     367
     368
     369
     370
     371
     372
     373
     374
     375
     376
     377
     378
     379
     380
     381
     382
     383
     384
     385
     386
     387
     388
     389
     390
     391
     392
     393
     394
     395
     396
     397
     398
     399
     400
     401
     402
     403
     404
     405
     406
     407
     408
     409
     410
     411
     412
     413
     414
     415
     416
     417
     418
     419
     420
     421
     422
     423
     424
     425
     426
     427
     428
     429
     430
     431
     432
     433
     434
     435
     436
     437
     438
     439
     440
     441
     442
     443
     444
     445
     446
     447
     448
     449
     450
     451
     452
     453
     454
     455
     456
     457
     458
     459
     460
     461
     462
     463
     464
     465
     466
     467
     468
     469
     470
     471
     472
     473
     474
     475
     476
     477
     478
     479
     480
     481
     482
     483
     484
     485
     486
     487
     488
     489
     490
     491
     492
     493
     494
     495
     496
     497
     498
     499
     500
     501
     502
     503
     504
     505
     506
     507
     508
     509
     510
     511
     512
     513
     514
     515
     516
     517
     518
     519
     520
     521
     522
     523
     524
     525
     526
     527
     528
     529
     530
     531
     532
     533
     534
     535
     536
     537
     538
     539
     540
     541
     542
     543
     544
     545
     546
     547
     548
     549
     550
     551
     552
     553
     554
     555
     556
     557
     558
     559
     560
     561
     562
     563
     564
     565
     566
     567
     568
     569
     570
     571
     572
     573
     574
     575
     576
     577
     578
     579
     580
     581
     582
     583
     584
     585
     586
     587
     588
     589
     590
     591
     592
     593
     594
     595
     596
     597
     598
     599
     600
     601
     602
     603
     604
     605
     606
     607
     608
     609
     610
     611
     612
     613
     614
     615
     616
     617
     618
     619
     620
     621
     622
     623
     624
     625
     626
     627
     628
     629
     630
     631
     632
     633
     634
     635
     636
     637
     638
     639
     640
     641
     642
     643
     644
     645
     646
     647
     648
     649
     650
     651
     652
     653
     654
     655
     656
     657
     658
     659
     660
     661
     662
     663
     664
     665
     666
     667
     668
     669
     670
     671
     672
     673
     674
     675
     676
     677
     678
     679
     680
     681
     682
     683
     684
     685
     686
     687
     688
     689
     690
     691
     692
     693
     694
     695
     696
     697
     698
     699
     700
     701
     702
     703
     704
     705
     706
     707
     708
     709
     710
     711
     712
     713
     714
     715
     716
     717
     718
     719
     720
     721
     722
     723
     724
     725
     726
     727
     728
     729
     730
     731
     732
     733
     734
     735
     736
     737
     738
     739
     740
     741
     742
     743
     744
     745
     746
     747
     748
     749
     750
     751
     752
     753
     754
     755
     756
     757
     758
     759
     760
     761
     762
     763
     764
     765
     766
     767
     768
     769
     770
     771
     772
     773
     774
     775
     776
     777
     778
     779
     780
     781
     782
     783
     784
     785
     786
     787
     788
     789
     790
     791
     792
     793
     794
     795
     796
     797
     798
     799
     800
     801
     802
     803
     804
     805
     806
     807
     808
     809
     810
     811
     812
     813
     814
     815
     816
     817
     818
     819
     820
     821
     822
     823
     824
     825
     826
     827
     828
     829
     830
     831
     832
     833
     834
     835
     836
     837
     838
     839
     840
     841
     842
     843
     844
     845
     846
     847
     848
     849
     850
     851
     852
     853
     854
     855
     856
     857
     858
     859
     860
     861
     862
     863
     864
     865
     866
     867
     868
     869
     870
     871
     872
     873
     874
     875
     876
     877
     878
     879
     880
     881
     882
     883
     884
     885
     886
     887
     888
     889
     890
     891
     892
     893
     894
     895
     896
     897
     898
     899
     900
     901
     902
     903
     904
     905
     906
     907
     908
     909
     910
     911
     912
     913
     914
     915
     916
     917
     918
     919
     920
     921
     922
     923
     924
     925
     926
     927
     928
     929
     930
     931
     932
     933
     934
     935
     936
     937
     938
     939
     940
     941
     942
     943
     944
     945
     946
     947
     948
     949
     950
     951
     952
     953
     954
     955
     956
     957
     958
     959
     960
     961
     962
     963
     964
     965
     966
     967
     968
     969
     970
     971
     972
     973
     974
     975
     976
     977
     978
     979
     980
     981
     982
     983
     984
     985
     986
     987
     988
     989
     990
     991
     992
     993
     994
     995
     996
     997
     998
     999
    1000
    1001
    1002
    1003
    1004
    1005
    1006
    1007
    1008
    1009
    1010
    1011
    1012
    1013
    1014
    1015
    1016
    1017
    1018
    1019
    1020
    1021
    1022
    1023
    1024
    1025
    1026
    1027
    1028
    1029
    1030
    1031
    1032
    1033
    1034
    1035
    1036
    1037
    1038
    1039
    1040
    1041
    1042
    1043
    1044
    1045
    1046
    1047
    1048
    1049
    1050
    1051
    1052
    1053
    1054
    1055
    1056
    1057
    1058
    1059
    1060
    1061
    1062
    1063
    1064
    1065
    1066
    1067
    1068
    1069
    1070
    1071
    1072
    1073
    1074
    1075
    1076
    1077
    1078
    1079
    1080
    1081
    1082
    1083
    1084
    1085
    1086
    1087
    1088
    1089
    1090
    1091
    1092
    1093
    1094
    1095
    1096
    1097
    1098
    1099
    1100
    1101
    1102
    1103
    1104
    1105
    1106
    1107
    1108
    1109
    1110
    1111
    1112
    1113
    1114
    1115
    1116
    1117
    1118
    1119
    1120
    1121
    1122
    1123
    1124
    1125
    1126
    1127
    1128
    1129
    1130
    1131
    1132
    1133
    1134
    1135
    1136
    1137
    1138
    1139
    1140
    1141
    1142
    1143
    1144
    1145
    1146
    1147
    1148
    1149
    1150
    1151
    1152
    1153
    1154
    1155
    1156
    1157
    1158
    1159
    1160
    1161
    1162
    1163
    1164
    1165
    1166
    1167
    1168
    1169
    1170
    1171
    1172
    1173
    1174
    1175
    1176
    1177
    1178
    1179
    1180
    1181
    1182
    1183
    1184
    1185
    1186
    1187
    1188
    1189
    1190
    1191
    1192
    1193
    1194
    1195
    1196
    1197
    1198
    1199
    1200
    1201
    1202
    1203
    1204
    1205
    1206
    1207
    1208
    1209
    1210
    1211
    1212
    1213
    1214
    1215
    1216
    1217
    1218
    1219
    1220
    1221
    1222
    1223
    1224
    1225
    1226
    1227
    1228
    1229
    1230
    1231
    1232
    1233
    1234
    1235
    1236
    1237
    1238
    1239
    1240
    1241
    1242
    1243
    1244
    1245
    1246
    1247
    1248
    1249
    1250
    1251
    1252
    1253
    1254
    1255
    1256
    1257
    1258
    1259
    1260
    1261
    1262
    1263
    1264
    1265
    1266
    1267
    1268
    1269
    1270
    1271
    1272
    1273
    1274
    1275
    1276
    1277
    1278
    1279
    1280
    1281
    1282
    1283
    1284
    1285
    1286
    1287
    1288
    1289
    1290
    1291
    1292
    1293
    1294
    1295
    1296
    1297
    1298
    1299
    1300
    1301
    1302
    1303
    1304
    1305
    1306
    1307
    1308
    1309
    1310
    1311
    1312
    1313
    1314
    1315
    1316
    1317
    1318
    1319
    1320
    1321
    1322
    1323
    1324
    1325
    1326
    1327
    1328
    1329
    1330
    1331
    1332
    1333
    1334
    1335
    1336
    1337
    1338
    1339
    1340
    1341
    1342
    1343
    1344
    1345
    1346
    1347
    1348
    1349
    1350
    1351
    1352
    1353
    1354
    1355
    1356
    1357
    1358
    1359
    1360
    1361
    1362
    1363
    1364
    1365
    1366
    1367
    1368
    1369
    1370
    1371
    1372
    1373
    1374
    1375
    1376
    1377
    1378
    1379
    1380
    1381
    1382
    1383
    1384
    1385
    1386
    1387
    1388
    1389
    1390
    1391
    1392
    1393
    1394
    1395
    1396
    1397
    1398
    1399
    1400
    1401
    1402
    1403
    1404
    1405
    1406
    1407
    1408
    1409
    1410
    1411
    1412
    1413
    1414
    1415
    1416
    1417
    1418
    1419
    1420
    1421
    1422
    1423
    1424
    1425
    1426
    1427
    1428
    1429
    1430
    1431
    1432
    1433
    1434
    1435
    1436
    1437
    1438
    1439
    1440
    1441
    1442
    1443
    1444
    1445
    1446
    1447
    1448
    1449
    1450
    1451
    1452
    1453
    1454
    1455
    1456
    1457
    1458
    1459
    1460
    1461
    1462
    1463
    1464
    1465
    1466
    1467
    1468
    1469
    1470
    1471
    1472
    1473
    1474
    1475
    1476
    1477
    1478
    1479
    1480
    1481
    1482
    1483
    1484
    1485
    1486
    1487
    1488
    1489
    1490
    1491
    1492
    1493
    1494
    1495
    1496
    1497
    1498
    1499
    1500
    1501
    1502
    1503
    1504
    1505
    1506
    1507
    1508
    1509
    1510
    1511
    1512
    1513
    1514
    1515
    1516
    1517
    1518
    1519
    1520
    1521
    1522
    1523
    1524
    1525
    1526
    1527
    1528
    1529
    1530
    1531
    1532
    1533
    1534
    1535
    1536
    1537
    1538
    1539
    1540
    1541
    1542
    1543
    1544
    1545
    1546
    1547
    1548
    1549
    1550
    1551
    1552
    1553
    1554
    1555
    1556
    1557
    1558
    1559
    1560
    1561
    1562
    1563
    1564
    1565
    1566
    1567
    1568
    1569
    1570
    1571
    1572
    1573
    1574
    1575
    1576
    1577
    1578
    1579
    1580
    1581
    1582
    1583
    1584
    1585
    1586
    1587
    1588
    1589
    1590
    1591
    1592
    1593
    1594
    1595
    1596
    1597
    1598
    1599
    1600
    1601
    1602
    1603
    1604
    1605
    1606
    1607
    1608
    1609
    1610
    1611
    1612
    1613
    1614
    1615
    1616
    1617
    1618
    1619
    1620
    1621
    1622
    1623
    1624
    1625
    1626
    1627
    1628
    1629
    1630
    1631
    1632
    1633
    1634
    1635
    1636
    1637
    1638
    1639
    1640
    1641
    1642
    1643
    1644
    1645
    1646
    1647
    1648
    1649
    1650
    1651
    1652
    1653
    1654
    1655
    1656
    1657
    1658
    1659
    1660
    1661
    1662
    1663
    1664
    1665
    1666
    1667
    1668
    1669
    1670
    1671
    1672
    1673
    1674
    1675
    1676
    1677
    1678
    1679
    1680
    1681
    1682
    1683
    1684
    1685
    1686
    1687
    1688
    1689
    1690
    1691
    1692
    1693
    1694
    1695
    1696
    1697
    1698
    1699
    1700
    1701
    1702
    1703
    1704
    1705
    1706
    1707
    1708
    1709
    1710
    1711
    1712
    1713
    1714
    1715
    1716
    1717
    1718
    1719
    1720
    1721
    1722
    1723
    1724
    1725
    1726
    1727
    1728
    1729
    1730
    1731
    1732
    1733
    1734
    1735
    1736
    1737
    1738
    1739
    1740
    1741
    1742
    1743
    1744
    1745
    1746
    1747
    1748
    1749
    1750
    1751
    1752
    1753
    1754
    1755
    1756
    1757
    1758
    1759
    1760
    1761
    1762
    1763
    1764
    1765
    1766
    1767
    1768
    1769
    1770
    1771
    1772
    1773
    1774
    1775
    1776
    1777
    1778
    1779
    1780
    1781
    1782
    1783
    1784
    1785
    1786
    1787
    1788
    1789
    1790
    1791
    1792
    1793
    1794
    1795
    1796
    1797
    1798
    1799
    1800
    1801
    1802
    1803
    1804
    1805
    1806
    1807
    1808
    1809
    1810
    1811
    1812
    1813
    1814
    1815
    1816
    1817
    1818
    1819
    1820
    1821
    1822
    1823
    1824
    1825
    1826
    1827
    1828
    1829
    1830
    1831
    1832
    1833
    1834
    1835
    1836
    1837
    1838
    1839
    1840
    1841
    1842
    1843
    1844
    1845
    1846
    1847
    1848
    1849
    1850
    1851
    1852
    1853
    1854
    1855
    1856
    1857
    1858
    1859
    1860
    1861
    1862
    1863
    1864
    1865
    1866
    1867
    1868
    1869
    1870
    1871
    1872
    1873
    1874
    1875
    1876
    1877
    1878
    1879
    1880
    1881
    1882
    1883
    1884
    1885
    1886
    1887
    1888
    1889
    1890
    1891
    1892
    1893
    1894
    1895
    1896
    1897
    1898
    1899
    1900
    1901
    1902
    1903
    1904
    1905
    1906
    1907
    1908
    1909
    1910
    1911
    1912
    1913
    1914
    1915
    1916
    1917
    1918
    1919
    1920
    1921
    1922
    1923
    1924
    1925
    1926
    1927
    1928
    1929
    1930
    1931
    1932
    1933
    1934
    1935
    1936
    1937
    1938
    1939
    1940
    1941
    1942
    1943
    1944
    1945
    1946
    1947
    1948
    1949
    1950
    1951
    1952
    1953
    1954
    1955
    1956
    1957
    1958
    1959
    1960
    1961
    1962
    1963
    1964
    1965
    1966
    1967
    1968
    1969
    1970
    1971
    1972
    1973
    1974
    1975
    1976
    1977
    1978
    1979
    1980
    1981
    1982
    1983
    1984
    1985
    1986
    1987
    1988
    1989
    1990
    1991
    1992
    1993
    1994
    1995
    1996
    1997
    1998
    1999
    2000
    2001
    2002
    2003
    2004
    2005
    2006
    2007
    2008
    2009
    2010
    2011
    2012
    2013
    2014
    2015
    2016
    2017
    2018
    2019
    2020
    2021
    2022
    2023
    2024
    2025
    2026
    2027
    2028
    2029
    2030
    2031
    2032
    2033
    2034
    2035
    2036
    2037
    2038
    2039
    2040
    2041
    2042
    2043
    2044
    2045
    2046
    2047
    2048
    2049
    2050
    2051
    2052
    2053
    2054
    2055
    2056
    2057
    2058
    2059
    2060
    2061
    2062
    2063
    2064
    2065
    2066
    2067
    2068
    2069
    2070
    2071
    2072
    2073
    2074
    2075
    2076
    2077
    2078
    2079
    2080
    2081
    2082
    2083
    2084
    2085
    2086
    2087
    2088
    2089
    2090
    2091
    2092
    2093
    2094
    2095
    2096
    2097
    2098
    2099
    2100
    2101
    2102
    2103
    2104
    2105
    2106
    2107
    2108
    2109
    2110
    2111
    2112
    2113
    2114
    2115
    2116
    2117
    2118
    2119
    2120
    2121
    2122
    2123
    2124
    2125
    2126
    2127
    2128
    2129
    2130
    2131
    2132
    2133
    2134
    2135
    2136
    2137
    2138
    2139
    2140
    2141
    2142
    2143
    2144
    2145
    2146
    2147
    2148
    2149
    2150
    2151
    2152
    2153
    2154
    2155
    2156
    2157
    2158
    2159
    2160
    2161
    2162
    2163
    
    -- ADS层
        -- Application Data Service
            -- Application:(数据仓库)应用
            -- Data:用户需求的统计结果数据
            -- Service:对外服务
            -- 1. ADS层保存的数据是最终的统计结果,无需做进一步的计算
                -- 不需要列式存储,也不需要snappy压缩
            -- 2. 统计结果的目的是对外提供服务,所以表不是最终数据存储的位置
                -- 需要将表中的数据同步到第三方存储(mysql)
                    -- ADS层的表最好是行式存储:tsv (DataX)
                    -- 压缩格式采用gzip
            -- 3. 统计结果的数据量,不会很多
                -- ADS层的表无需分区(分区是因为数据量大,分区作为提前筛选,但是ADS层数据量小,无需分区)
            -- 4. 表设计
                -- ODS层:表的结构依托于数据源的数据结构(ER模型)
                -- DIM层:遵循维度模型的维度表的设计理念(维度越丰富越好)(表、字段(丰富)、编码与文字共存、沉淀)
                -- DWD层:遵循维度模型的事实表的设计理念(粒度越细越好)(描述行为、度量值)
                -- ADS层:客户需求(不要额外添加)
        --基础概念
            -- 维度:分析数据的角度
            -- 粒度:描述数据的详细程度
            -- 统计周期:统计的时候,数据统计时间范围
                -- 2022-06-08(最近一周):02 03 04 05 06 07 08
                -- 2022-06-09(最近一周):03 04 05 06 07 08 09
                -- 2022-06-10(最近一周):04 05 06 07 08 09 10
            -- 统计粒度:分析数据的角度(站在哪一个角度统计数据)
                -- 维度越丰富,粒度越细
            -- 指标:客户想要的一个结果数值
    
    -- 各品牌商品下单统计
        -- 统计的行为:下单
        -- 分析的角度:品牌
        -- 指标:下单数量、下单人数
        -- 建表语句
            -- 统计日期:以获取数据那一天为准(比如获取8号数据(9号跑代码))
    DROP TABLE IF EXISTS ads_order_stats_by_tm;
    CREATE EXTERNAL TABLE ads_order_stats_by_tm
    (
        `dt`                      STRING COMMENT '统计日期',
        `recent_days`             BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
        `tm_id`                   STRING COMMENT '品牌ID',
        `tm_name`                 STRING COMMENT '品牌名称',
        `order_count`             BIGINT COMMENT '下单数',
        `order_user_count`        BIGINT COMMENT '下单人数'
    ) COMMENT '各品牌商品下单统计'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_order_stats_by_tm/';
    
    -- 数据装载
        -- 统计指标分析
            -- 将负责的指标分解成小的,简单的指标
            -- 指标分析
                -- 1. 原子指标(最基础的统计值,不可分割)
                    -- 业务过程(业务行为) + 度量值 + 聚合逻辑
                    -- 下单 + (order_id)次数 + 聚合逻辑
    /*
        zs 2022-06-08 AAAA  鞋  1000
        zs 2022-06-08 AAAA 衣服 1500
        zs 2022-06-08 AAAA 帽子 500
    */
    -- select
    --     count(distinct order_id)
    -- from dwd_trade_order_detail_inc;
    
                -- 2. 派生指标
                    -- 基于原子指标,增加其他的条件、角度之类
                        -- 派生指标 = 原子指标 + 统计周期(最近1天) + 业务限定 + 统计粒度
                            -- 统计周期和业务限定其实都是数据筛选条件,但是不一样
                                -- 统计周期一般指的就是数据时间范围(分区字段的过滤:过滤文件夹)
                                -- 业务限定一般指的就是数据约束条件(数据字段的过滤:过滤文件)
    -- select
    --     count(distinct order_id)
    -- from dwd_trade_order_detail_inc
    -- where dt >= date_sub('2022-06-08', 0) and dt <= '2022-06-08'
    -- group by 品牌
    --
    -- select
    --     count(distinct order_id)
    -- from dwd_trade_order_detail_inc
    -- where dt >= date_sub('2022-06-08', 6) and dt <= '2022-06-08'
    -- group by 品牌
    --
    -- select
    --     count(distinct order_id)
    -- from dwd_trade_order_detail_inc
    -- where dt >= date_sub('2022-06-08', 29) and dt <= '2022-06-08'
    -- group by 品牌
    
                -- 3. 衍生指标
                    -- 将多个派生指标通过计算获取
    -- 最近 1 7 30 天
        -- 2022-06-08   1   结果
        -- 2022-06-08   7   结果
        -- 2022-06-08   30  结果
    -- 预期统计结果 <= 11 * 3 = 33
    -- 预期统计结果:最近1天(5),最近7天(8),最近10天(10)
    
    -- 最近1天 各个品牌 下单数 下单人数统计
        -- 统计周期其实就是数据的时间范围,一般会在where子句中添加dt条件
        -- 业务限定其实就是数据的约束条件,一般会在where子句中添加业务条件
        -- 统计粒度其实就是数据的分析维度,一般会在group by子句中添加维度字段
    
    -- 分组聚合的场合下,哪些字段可以出现在select子句中
        -- 1. 常量
        -- 2. 聚合函数内的字段
        -- 3. 参与分组的字段
    -- 多个字段参与分组的时候,统计值的含义
        -- 1. 如果多个字段存在上下级,所属关系,那么统计结果和下级字段相关,上级字段参与分组纯粹是用于补全数据(不参与分组,不能出现在查询结果中)
        -- 2. 如果多个字段存在关联关系,那么统计结果和具有唯一性字段相关,其他字段用于补全数据
        -- 3. 如果多个字段没有任何关系,那么统计结果和所有的字段相关
            -- group by (userId, skuId)
    select
        '2022-06-08'                     ,-- STRING COMMENT '统计日期',
        1            ,-- BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
        `tm_id`                  ,-- STRING COMMENT '品牌ID',
        `tm_name`                ,-- STRING COMMENT '品牌名称',
        count(distinct order_id) `order_count`            ,-- BIGINT COMMENT '下单数',
        count(distinct user_id) `order_user_count`       -- BIGINT COMMENT '下单人数'
    from (
        select
            order_id,
            user_id,
            sku_id
        from dwd_trade_order_detail_inc
        where dt = '2022-06-08'
    ) od left join (
        select
            id,
            tm_id,
            tm_name
        from dim_sku_full
        where dt = '2022-06-08'
    ) sku on od.sku_id = sku_id
    group by tm_id, tm_name;
    
    -- 最近7天
    select
        '2022-06-08'                     ,-- STRING COMMENT '统计日期',
        7            ,-- BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
        `tm_id`                  ,-- STRING COMMENT '品牌ID',
        `tm_name`                ,-- STRING COMMENT '品牌名称',
        count(distinct order_id) `order_count`            ,-- BIGINT COMMENT '下单数',
        count(distinct user_id) `order_user_count`       -- BIGINT COMMENT '下单人数'
    from (
        select
            order_id,
            user_id,
            sku_id
        from dwd_trade_order_detail_inc
        where dt >= date_sub('2022-06-08', 6) and dt <= '2022-06-08'
    ) od left join (
        select
            id,
            tm_id,
            tm_name
        from dim_sku_full
        where dt >= date_sub('2022-06-08', 6) and dt <= '2022-06-08'
        group by id, tm_id, tm_name
    ) sku on od.sku_id = sku_id
    group by tm_id, tm_name;
    
    -----------------------------------
    
    select
        '2022-06-08'                     ,-- STRING COMMENT '统计日期',
        7            ,-- BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
        `tm_id`                  ,-- STRING COMMENT '品牌ID',
        `tm_name`                ,-- STRING COMMENT '品牌名称',
        count(distinct order_id) `order_count`            ,-- BIGINT COMMENT '下单数',
        count(distinct user_id) `order_user_count`       -- BIGINT COMMENT '下单人数'
    from (
        select
            order_id,
            user_id,
            sku_id
        from dwd_trade_order_detail_inc
        where dt >= date_sub('2022-06-08', 6) and dt <= '2022-06-08'
    ) od left join (
        select
            id,
            tm_id,
            tm_name
        from dim_sku_full
        where dt = '2022-06-08'
        -- 查不出来但是能关联(最后一天一定是最全的数据)
    ) sku on od.sku_id = sku_id
    group by tm_id, tm_name;
    
    -- 最近30天
    select
        '2022-06-08'                     ,-- STRING COMMENT '统计日期',
        30            ,-- BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
        `tm_id`                  ,-- STRING COMMENT '品牌ID',
        `tm_name`                ,-- STRING COMMENT '品牌名称',
        count(distinct order_id) `order_count`            ,-- BIGINT COMMENT '下单数',
        count(distinct user_id) `order_user_count`       -- BIGINT COMMENT '下单人数'
    from (
        select
            order_id,
            user_id,
            sku_id
        from dwd_trade_order_detail_inc
        where dt >= date_sub('2022-06-08', 29) and dt <= '2022-06-08'
    ) od left join (
        select
            id,
            tm_id,
            tm_name
        from dim_sku_full
        where dt = '2022-06-08'
        -- 查不出来但是能关联(最后一天一定是最全的数据)
    ) sku on od.sku_id = sku_id
    group by tm_id, tm_name;
    
    --------------------------------------------------
    -- 保留旧的,插入新的(全表)
    insert overwrite table ads_order_stats_by_tm
    select * from ads_order_stats_by_tm
    union -- 去重
    select * from (select '2022-06-08',-- STRING COMMENT '统计日期',
                          1,-- BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
                          `tm_id`,-- STRING COMMENT '品牌ID',
                          `tm_name`,-- STRING COMMENT '品牌名称',
                          count(distinct order_id) `order_count`,-- BIGINT COMMENT '下单数',
                          count(distinct user_id)  `order_user_count` -- BIGINT COMMENT '下单人数'
                   from (select order_id,
                                user_id,
                                sku_id
                         from dwd_trade_order_detail_inc
                         where dt = '2022-06-08') od
                            left join (select id,
                                              tm_id,
                                              tm_name
                                       from dim_sku_full
                                       where dt = '2022-06-08') sku on od.sku_id = sku_id
                   group by tm_id, tm_name
                   union all
                   select '2022-06-08',-- STRING COMMENT '统计日期',
                          7,-- BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
                          `tm_id`,-- STRING COMMENT '品牌ID',
                          `tm_name`,-- STRING COMMENT '品牌名称',
                          count(distinct order_id) `order_count`,-- BIGINT COMMENT '下单数',
                          count(distinct user_id)  `order_user_count` -- BIGINT COMMENT '下单人数'
                   from (select order_id,
                                user_id,
                                sku_id
                         from dwd_trade_order_detail_inc
                         where dt >= date_sub('2022-06-08', 6)
                           and dt <= '2022-06-08') od
                            left join (select id,
                                              tm_id,
                                              tm_name
                                       from dim_sku_full
                                       where dt = '2022-06-08'
                       -- 查不出来但是能关联(最后一天一定是最全的数据)
                   ) sku on od.sku_id = sku_id
                   group by tm_id, tm_name
                   union all
                   select '2022-06-08',-- STRING COMMENT '统计日期',
                          30,-- BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
                          `tm_id`,-- STRING COMMENT '品牌ID',
                          `tm_name`,-- STRING COMMENT '品牌名称',
                          count(distinct order_id) `order_count`,-- BIGINT COMMENT '下单数',
                          count(distinct user_id)  `order_user_count` -- BIGINT COMMENT '下单人数'
                   from (select order_id,
                                user_id,
                                sku_id
                         from dwd_trade_order_detail_inc
                         where dt >= date_sub('2022-06-08', 29)
                           and dt <= '2022-06-08') od
                            left join (select id,
                                              tm_id,
                                              tm_name
                                       from dim_sku_full
                                       where dt = '2022-06-08'
                       -- 查不出来但是能关联(最后一天一定是最全的数据)
                   ) sku on od.sku_id = sku_id
                   group by tm_id, tm_name) t;
    
    -- 各品类商品下单统计
        -- 建表语句
    DROP TABLE IF EXISTS ads_order_stats_by_cate;
    CREATE EXTERNAL TABLE ads_order_stats_by_cate
    (
        `dt`                      STRING COMMENT '统计日期',
        `recent_days`             BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
        `category1_id`            STRING COMMENT '一级品类ID',
        `category1_name`          STRING COMMENT '一级品类名称',
        `category2_id`            STRING COMMENT '二级品类ID',
        `category2_name`          STRING COMMENT '二级品类名称',
        `category3_id`            STRING COMMENT '三级品类ID',
        `category3_name`          STRING COMMENT '三级品类名称',
        `order_count`             BIGINT COMMENT '下单数',
        `order_user_count`        BIGINT COMMENT '下单人数'
    ) COMMENT '各品类商品下单统计'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_order_stats_by_cate/';
    
    insert overwrite table ads_order_stats_by_cate
    select * from ads_order_stats_by_cate
    union
    select * from (
    -- 最近1天
                      select '2022-06-08',
                             1,
                             `category1_id`,
                             `category1_name`,
                             `category2_id`,
                             `category2_name`,
                             `category3_id`,
                             `category3_name`,
                             count(distinct order_id) order_count,
                             count(distinct user_id)  order_user_count
                      from (select order_id,
                                   user_id,
                                   sku_id
                            from dwd_trade_order_detail_inc
                            where dt = '2022-06-08') od
                               left join (select id,
                                                 category1_id,
                                                 category1_name,
                                                 category2_id,
                                                 category2_name,
                                                 category3_id,
                                                 category3_name
                                          from dim_sku_full
                                          where dt = '2022-06-08') sku on od.sku_id = sku.id
                      group by
                          -- 关联关系(3_id)
                          `category1_id`,
                          `category1_name`,
                          `category2_id`,
                          `category2_name`,
                          `category3_id`,
                          `category3_name`
                      union all
    -- 最近7天
                      select '2022-06-08',
                             7,
                             `category1_id`,
                             `category1_name`,
                             `category2_id`,
                             `category2_name`,
                             `category3_id`,
                             `category3_name`,
                             count(distinct order_id) order_count,
                             count(distinct user_id)  order_user_count
                      from (select order_id,
                                   user_id,
                                   sku_id
                            from dwd_trade_order_detail_inc
                            where dt >= date_sub('2022-06-08', 6)
                              and dt <= '2022-06-08') od
                               left join (select id,
                                                 category1_id,
                                                 category1_name,
                                                 category2_id,
                                                 category2_name,
                                                 category3_id,
                                                 category3_name
                                          from dim_sku_full
                                          where dt = '2022-06-08') sku on od.sku_id = sku.id
                      group by
                          -- 关联关系(3_id)
                          `category1_id`,
                          `category1_name`,
                          `category2_id`,
                          `category2_name`,
                          `category3_id`,
                          `category3_name`
                      union all
    -- 最近30天
                      select '2022-06-08',
                             30,
                             `category1_id`,
                             `category1_name`,
                             `category2_id`,
                             `category2_name`,
                             `category3_id`,
                             `category3_name`,
                             count(distinct order_id) order_count,
                             count(distinct user_id)  order_user_count
                      from (select order_id,
                                   user_id,
                                   sku_id
                            from dwd_trade_order_detail_inc
                            where dt >= date_sub('2022-06-08', 29)
                              and dt <= '2022-06-08') od
                               left join (select id,
                                                 category1_id,
                                                 category1_name,
                                                 category2_id,
                                                 category2_name,
                                                 category3_id,
                                                 category3_name
                                          from dim_sku_full
                                          where dt = '2022-06-08') sku on od.sku_id = sku.id
                      group by
                          -- 关联关系(3_id)
                          `category1_id`,
                          `category1_name`,
                          `category2_id`,
                          `category2_name`,
                          `category3_id`,
                          `category3_name`) t;
    
    -- 性能如何提升?
        -- join(X)
        -- 可以减少数据量(X)
        -- 可以重复计算(OK)
        -- 数据重复读取(OK)
    -- 优化思路
        -- 将最近1天的数据保存到一张表中
            -- 最近7天和最近30天数据从最近1天的统计表中获取数据,进行进一步的计算
    
    -- ODS(X) 对接数据源
    -- DIM(X) 分析数据作为维度
    -- DWD(X) 存储业务行为数据
    -- DWS(OK) 预聚合,保存中间计算结果
        -- 中间计算结果不是最终结果表
            -- 数据量:增加分区
            -- 需要进一步的计算
                -- 存储方式:列式存储
                -- 压缩语句:snappy
    -- ADS(X) 无需再做进一步计算的统计结果
    DROP TABLE IF EXISTS dws_order_stats_by_tm_1d;
    CREATE EXTERNAL TABLE dws_order_stats_by_tm_1d
    (
        `tm_id`                   STRING COMMENT '品牌ID',
        `tm_name`                 STRING COMMENT '品牌名称',
        `order_count_1d`             BIGINT COMMENT '下单数',
        `order_user_count_1d`        BIGINT COMMENT '下单人数'
    ) COMMENT '各品牌商品最近1天下单统计'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_order_stats_by_tm_1d/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- 将最近1天的统计结果保存到1d表中
    insert overwrite table dws_order_stats_by_tm_1d partition (dt = '2022-06-08')
    select
        `tm_id`                  ,-- STRING COMMENT '品牌ID',
        `tm_name`                ,-- STRING COMMENT '品牌名称',
        count(distinct order_id) `order_count_1d`            ,-- BIGINT COMMENT '下单数',
        count(distinct user_id) `order_user_count_1d`       -- BIGINT COMMENT '下单人数'
    from (
        select
            order_id,
            user_id,
            sku_id
        from dwd_trade_order_detail_inc
        where dt = '2022-06-08'
    ) od left join (
        select
            id,
            tm_id,
            tm_name
        from dim_sku_full
        where dt = '2022-06-08'
    ) sku on od.sku_id = sku_id
    group by tm_id, tm_name;
    
    -- 从1d表中获取最近1天,最近7天,最近30天数据,保存到ADS层的表中
    insert overwrite table ads_order_stats_by_tm
    select * from ads_order_stats_by_tm
    union
    select * from (
    -- 最近1天
    select
        '2022-06-08',
        1,
        tm_id,
        tm_name,
        order_count_1d,
        order_user_count_1d
    from dws_order_stats_by_tm_1d
    where dt = '2022-06-08'
    union all
    -- 最近7天
    select
        '2022-06-08',
        7,
        tm_id,
        tm_name,
        sum(order_count_1d),
        sum(order_user_count_1d)
    from dws_order_stats_by_tm_1d
    where dt >= date_sub('2022-06-08', 6) and dt <= '2022-06-08'
    group by tm_id, tm_name
    union all
    -- 最近30天
    select
        '2022-06-08',
        30,
        tm_id,
        tm_name,
        sum(order_count_1d),
        sum(order_user_count_1d)
    from dws_order_stats_by_tm_1d
    where dt >= date_sub('2022-06-08', 29) and dt <= '2022-06-08'
    group by tm_id, tm_name) t;
    
    -- 当前的问题:读三次相同的数据,使用在三个不同的场景
    -- 解决思路:读一次数据,使用在三个不同的场景
        -- 使用炸裂函数
    select
        *
    from (
        select 'a' name
    ) t lateral view explode(array(1, 7, 30)) tmp as name1
    where name1 != 7;
    
    /*
            -- 1d表中的数据
            zhangsan    2022-06-08    order
            zhangsan    2022-06-07    order
            zhangsan    2022-06-06    order
            zhangsan    2022-06-05    order
            zhangsan    2022-06-04    order
            zhangsan    2022-06-03    order
            zhangsan    2022-06-02    order
            zhangsan    2022-06-01    order
    
            -- 最近1天
            zhangsan    2022-06-08    order
            -- 最近7天
            zhangsan    2022-06-08    order
            zhangsan    2022-06-07    order
            zhangsan    2022-06-06    order
            zhangsan    2022-06-05    order
            zhangsan    2022-06-04    order
            zhangsan    2022-06-03    order
            zhangsan    2022-06-02    order
            -- 最近30天
            zhangsan    2022-06-08    order
            zhangsan    2022-06-07    order
            zhangsan    2022-06-06    order
            zhangsan    2022-06-05    order
            zhangsan    2022-06-04    order
            zhangsan    2022-06-03    order
            zhangsan    2022-06-02    order
            zhangsan    2022-06-01    order
    
            1. 获取时间范围最大的数据集
            zhangsan    2022-06-08    order
            zhangsan    2022-06-07    order
            zhangsan    2022-06-06    order
            zhangsan    2022-06-05    order
            zhangsan    2022-06-04    order
            zhangsan    2022-06-03    order
            zhangsan    2022-06-02    order
            zhangsan    2022-06-01    order
            2. 奖查询的数据集在内存中进行炸裂操作(3),变成多份
            zhangsan    2022-06-08    order     1
            zhangsan    2022-06-07    order     1
            zhangsan    2022-06-06    order     1
            zhangsan    2022-06-05    order     1
            zhangsan    2022-06-04    order     1
            zhangsan    2022-06-03    order     1
            zhangsan    2022-06-02    order     1
            zhangsan    2022-06-01    order     1
            zhangsan    2022-06-08    order     7
            zhangsan    2022-06-07    order     7
            zhangsan    2022-06-06    order     7
            zhangsan    2022-06-05    order     7
            zhangsan    2022-06-04    order     7
            zhangsan    2022-06-03    order     7
            zhangsan    2022-06-02    order     7
            zhangsan    2022-06-01    order     7
            zhangsan    2022-06-08    order     30
            zhangsan    2022-06-07    order     30
            zhangsan    2022-06-06    order     30
            zhangsan    2022-06-05    order     30
            zhangsan    2022-06-04    order     30
            zhangsan    2022-06-03    order     30
            zhangsan    2022-06-02    order     30
            zhangsan    2022-06-01    order     30
            3. 将炸裂后的数据进行筛选过滤,保留有效数据
            zhangsan    2022-06-08    order     1     (OK)
            zhangsan    2022-06-07    order     1     (X)
            zhangsan    2022-06-06    order     1     (X)
            zhangsan    2022-06-05    order     1     (X)
            zhangsan    2022-06-04    order     1     (X)
            zhangsan    2022-06-03    order     1     (X)
            zhangsan    2022-06-02    order     1     (X)
            zhangsan    2022-06-01    order     1     (X)
            zhangsan    2022-06-08    order     7     (OK)
            zhangsan    2022-06-07    order     7     (OK)
            zhangsan    2022-06-06    order     7     (OK)
            zhangsan    2022-06-05    order     7     (OK)
            zhangsan    2022-06-04    order     7     (OK)
            zhangsan    2022-06-03    order     7     (OK)
            zhangsan    2022-06-02    order     7     (OK)
            zhangsan    2022-06-01    order     7     (X)
            zhangsan    2022-06-08    order     30    (OK)
            zhangsan    2022-06-07    order     30    (OK)
            zhangsan    2022-06-06    order     30    (OK)
            zhangsan    2022-06-05    order     30    (OK)
            zhangsan    2022-06-04    order     30    (OK)
            zhangsan    2022-06-03    order     30    (OK)
            zhangsan    2022-06-02    order     30    (OK)
            zhangsan    2022-06-01    order     30    (OK)
            4.将过滤后的数据按照标记进行分组,然后统计
            zhangsan    2022-06-08    order     1     (OK)
    
            zhangsan    2022-06-08    order     7     (OK)
            zhangsan    2022-06-07    order     7     (OK)
            zhangsan    2022-06-06    order     7     (OK)
            zhangsan    2022-06-05    order     7     (OK)
            zhangsan    2022-06-04    order     7     (OK)
            zhangsan    2022-06-03    order     7     (OK)
            zhangsan    2022-06-02    order     7     (OK)
    
            zhangsan    2022-06-08    order     30    (OK)
            zhangsan    2022-06-07    order     30    (OK)
            zhangsan    2022-06-06    order     30    (OK)
            zhangsan    2022-06-05    order     30    (OK)
            zhangsan    2022-06-04    order     30    (OK)
            zhangsan    2022-06-03    order     30    (OK)
            zhangsan    2022-06-02    order     30    (OK)
            zhangsan    2022-06-01    order     30    (OK)
     */
    insert overwrite table ads_order_stats_by_tm
    select * from ads_order_stats_by_tm
    union
    select
        '2022-06-08',
        days,
        tm_id,
        tm_name,
        sum(order_count_1d),
        sum(order_user_count_1d)
    from dws_order_stats_by_tm_1d lateral view explode(`array`(1, 7, 30)) tmp as days
    where dt >= date_sub('2022-06-08', days - 1) and dt <= '2022-06-08'
    group by days, tm_id, tm_name
    
    DROP TABLE IF EXISTS dws_order_stats_by_tm_1d;
    CREATE EXTERNAL TABLE dws_order_stats_by_tm_1d
    (
        `tm_id`                   STRING COMMENT '品牌ID',
        `tm_name`                 STRING COMMENT '品牌名称',
        `order_count_1d`             BIGINT COMMENT '下单数',
        `order_user_count_1d`        BIGINT COMMENT '下单人数'
    ) COMMENT '各品牌商品最近1天下单统计'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_order_stats_by_tm_1d/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    insert overwrite table dws_order_stats_by_tm_1d partition (dt = '2022-06-08')
    select
        `tm_id`                  ,-- STRING COMMENT '品牌ID',
        `tm_name`                ,-- STRING COMMENT '品牌名称',
        count(distinct order_id) `order_count_1d`            ,-- BIGINT COMMENT '下单数',
        count(distinct user_id) `order_user_count_1d`       -- BIGINT COMMENT '下单人数'
    from (
        select
            order_id,
            user_id,
            sku_id
        from dwd_trade_order_detail_inc
        where dt = '2022-06-08'
    ) od left join (
        select
            id,
            tm_id,
            tm_name
        from dim_sku_full
        where dt = '2022-06-08'
    ) sku on od.sku_id = sku_id
    group by tm_id, tm_name;
    
    
    DROP TABLE IF EXISTS dws_order_stats_by_tm_7d;
    CREATE EXTERNAL TABLE dws_order_stats_by_tm_7d
    (
        `tm_id`                   STRING COMMENT '品牌ID',
        `tm_name`                 STRING COMMENT '品牌名称',
        `order_count_7d`             BIGINT COMMENT '下单数',
        `order_user_count_7d`        BIGINT COMMENT '下单人数'
    ) COMMENT '各品牌商品最近7天下单统计'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_order_stats_by_tm_7d/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    insert overwrite table dws_order_stats_by_tm_7d partition (dt = '2022-06-08')
    select
        tm_id,
        tm_name,
        sum(order_count_1d) order_count_7d,
        sum(order_user_count_1d) order_user_count_7d
    from dws_order_stats_by_tm_1d
    where dt >= date_sub('2022-06-08', 6) and dt <= '2022-06-08'
    group by tm_id, tm_name;
    
    DROP TABLE IF EXISTS dws_order_stats_by_tm_30d;
    CREATE EXTERNAL TABLE dws_order_stats_by_tm_30d
    (
        `tm_id`                   STRING COMMENT '品牌ID',
        `tm_name`                 STRING COMMENT '品牌名称',
        `order_count_30d`             BIGINT COMMENT '下单数',
        `order_user_count_30d`        BIGINT COMMENT '下单人数'
    ) COMMENT '各品牌商品最近30天下单统计'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_order_stats_by_tm_30d/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    insert overwrite table dws_order_stats_by_tm_30d partition (dt = '2022-06-08')
    select
        tm_id,
        tm_name,
        sum(order_count_1d) order_count_30d,
        sum(order_user_count_1d) order_user_count_30d
    from dws_order_stats_by_tm_1d
    where dt >= date_sub('2022-06-08', 29) and dt <= '2022-06-08'
    group by tm_id, tm_name;
    
    --------------------------------------------------------------------------------
    -- nd表
        -- 就是封装了7、30天的统计结果
    DROP TABLE IF EXISTS dws_order_stats_by_tm_nd;
    CREATE EXTERNAL TABLE dws_order_stats_by_tm_nd
    (
        `tm_id`                   STRING COMMENT '品牌ID',
        `tm_name`                 STRING COMMENT '品牌名称',
        `order_count_7d`             BIGINT COMMENT '下单数',
        `order_user_count_7d`        BIGINT COMMENT '下单人数',
        `order_count_30d`             BIGINT COMMENT '下单数',
        `order_user_count_30d`        BIGINT COMMENT '下单人数'
    ) COMMENT '各品牌商品最近n天下单统计'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_order_stats_by_tm_nd/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    insert overwrite table dws_order_stats_by_tm_nd partition (dt = '2022-06-08')
    select
        tm_id,
        tm_name,
        sum(if (dt >= date_sub('2022-06-08', 6), order_count_1d, 0)) order_count_7d,
        sum(if (dt >= date_sub('2022-06-08', 6), order_user_count_1d, 0)) order_user_count_7d,
        sum(order_count_1d) order_count_30d,
        sum(order_user_count_1d) order_user_count_30d
    from dws_order_stats_by_tm_1d
    where dt >= date_sub('2022-06-08', 29) and dt <= '2022-06-08'
    group by tm_id, tm_name;
    
    ------------------------------------------------------------------------------------
    -- 假设已经将数据封装为1d表和nd表,如何计算最终结果
    DROP TABLE IF EXISTS ads_order_stats_by_tm;
    CREATE EXTERNAL TABLE ads_order_stats_by_tm
    (
        `dt`                      STRING COMMENT '统计日期',
        `recent_days`             BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
        `tm_id`                   STRING COMMENT '品牌ID',
        `tm_name`                 STRING COMMENT '品牌名称',
        `order_count`             BIGINT COMMENT '下单数',
        `order_user_count`        BIGINT COMMENT '下单人数'
    ) COMMENT '各品牌商品下单统计'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_order_stats_by_tm/';
    
    insert overwrite table ads_order_stats_by_tm
    select * from ads_order_stats_by_tm
    union
        select * from (
        select
            '2022-06-08',
            1,
            tm_id,
            tm_name,
            order_count_1d,
            order_user_count_1d
        from dws_order_stats_by_tm_1d
        where dt = '2022-06-08'
        union all
        select
            '2022-06-08',
            7,
            tm_id,
            tm_name,
            order_count_7d,
            order_user_count_7d
        from dws_order_stats_by_tm_nd
        where dt = '2022-06-08'
        union all
        select
        '2022-06-08',
        30,
        tm_id,
        tm_name,
        order_count_30d,
        order_user_count_30d
    from dws_order_stats_by_tm_nd
    where dt = '2022-06-08'
    ) t;
    
    -- 新增下单用户统计
        -- 以前这个用户没有下过订单,最近1天,第一回下订单,称之为新增下单用户
        -- 以前这个用户没有下过订单,最近7天,第一回下订单,称之为新增下单用户
        -- 以前这个用户没有下过订单,最近30天,第一回下订单,称之为新增下单用户
        -- 建表语句
    DROP TABLE IF EXISTS ads_new_order_user_stats;
    CREATE EXTERNAL TABLE ads_new_order_user_stats
    (
        `dt`                   STRING COMMENT '统计日期',
        `recent_days`          BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
        `new_order_user_count` BIGINT COMMENT '新增下单人数'
    ) COMMENT '新增下单用户统计'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_new_order_user_stats/';
    
    -- 新增:以前没做过,今天是第一回
        -- 判断1天前用户没有出现过
    insert overwrite table ads_new_order_user_stats
    select * from ads_new_order_user_stats
    union
        select * from (
        select
            '2022-06-08',
            1,
            count(distinct  user_id)
        from dwd_trade_order_detail_inc
        where dt = '2022-06-08'
        and user_id not in (
            select
                *
            from dwd_trade_order_detail_inc
            where dt < '2022-06-08'
        )
        union all
        select
            '2022-06-08',
            7,
            count(distinct  user_id)
        from dwd_trade_order_detail_inc
        where dt >= date_sub('2022-06-08', 6) and dt <= '2022-06-08'
        and user_id not in (
            select
                *
            from dwd_trade_order_detail_inc
            where dt < date_sub('2022-06-08', 6)
        )
        union all
        select
        '2022-06-08',
        30,
        count(distinct  user_id)
    from dwd_trade_order_detail_inc
    where dt >= date_sub('2022-06-08', 29) and dt <= '2022-06-08'
    and user_id not in (
        select
            *
        from dwd_trade_order_detail_inc
        where dt < date_sub('2022-06-08', 29)
    )
    ) t;
    
    -- 需求:统计最近1天,7天,30天新增注册用户
    DROP TABLE IF EXISTS ads_new_reg_user_stats;
    CREATE EXTERNAL TABLE ads_new_reg_user_stats
    (
        `dt`                   STRING COMMENT '统计日期',
        `recent_days`          BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
        `new_reg_user_count` BIGINT COMMENT '新增下单人数'
    ) COMMENT '新增注册用户统计'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_new_reg_user_stats/';
    
    insert overwrite table ads_new_reg_user_stats
    select * from ads_new_reg_user_stats
    union
    select * from (
        select '2022-06-08',
                          1,
                          count(*)
                   from dwd_user_register_inc
                   where dt = '2022-06-08'
        union all
        select '2022-06-08',
              7,
              count(*)
       from dwd_user_register_inc
       where dt >= date_sub('2022-06-08', 6)
         and dt <= '2022-06-08'
        union all
        select '2022-06-08',
                          30,
                          count(*)
                   from dwd_user_register_inc
                   where dt >= date_sub('2022-06-08', 29)
                     and dt <= '2022-06-08'
    ) t;
    
    -- 需求:统计最近1天,7天,30天新增下单用户(难)
        -- 新增下单(用户第一次下单)
    -- 需求:统计最近1天,7天,30天新增注册用户(简单)
        -- 新增注册(用户第一次注册)
    
    ---------------------------------------------------------------------------------
    -- 如果将一个表的所有数据获取之后再进行统计,那么这张表称为历史至今表,一般称之为td表
    DROP TABLE IF EXISTS dws_first_order_stats;
    CREATE EXTERNAL TABLE dws_first_order_stats
    (
        `user_id`          BIGINT COMMENT '用户ID',
        `first_order_date` BIGINT COMMENT '用户首次下单时间'
    ) COMMENT '用户首次下单统计'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_first_order_stats/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- 首日
    -- all table data
    insert overwrite table dws_first_order_stats partition (dt = '2022-06-08')
    select
        user_id,
        min(date_id) first_order_date
    from dwd_trade_order_detail_inc
    group by user_id;
    
    -- 2022-06-08 result + 2022-06-09 data => final result
    -- insert overwrite table dws_first_order_stats partition (dt = '2022-06-09')
    -- select
    --     user_id,
    --     min(date_id) first_order_date
    -- from dwd_trade_order_detail_inc
    -- group by user_id
    
    -- 每日
    insert overwrite table dws_first_order_stats partition (dt = '2022-06-09')
    select
        user_id,
        min(first_order_date)
    from (
        select
            user_id,
            first_order_date
        from dws_first_order_stats
        where dt = date_sub('2022-06-09', 1)
        union all
        select
            user_id,
            '2022-06-09'
        from dwd_trade_order_detail_inc
        where dt = '2022-06-09'
    ) t group by user_id;
    
    ---------------------------------------------------------------------------
    insert overwrite table ads_new_order_user_stats
    select * from ads_new_order_user_stats
    union
    select * from (
        select '2022-06-08',
                          1,
                          count(*)
                   from dws_first_order_stats
                   where dt = '2022-06-08'
                     and first_order_date = '2022-06-08'
        union all
        -- dt表示统计时间,而不是业务时间
        -- 统计周期其实指的是业务时间范围,所以条件判断中不能使用dt字段进行范围的查询
        select '2022-06-08',
              7,
              count(*)
       from dws_first_order_stats
       where dt = '2022-06-08'
         and first_order_date >= date_sub('2022-06-08', 6)
         and first_order_date <= '2022-06-08'
        union all
        select '2022-06-08',
                          30,
                          count(*)
                   from dws_first_order_stats
                   where dt = '2022-06-08'
                     and first_order_date >= date_sub('2022-06-08', 29)
                     and first_order_date <= '2022-06-08'
    ) t;
    
    -------------------------------------------------------------------
    -- 之前设计的表是有问题的
        -- 1d表
        -- nd表
        -- td表
    -------------------------------------------------------------------
    /*
            zhangsan    2022-06-08      order
            zhangsan    2022-06-07      order
            zhangsan    2022-06-06      order
            zhangsan    2022-06-05      order
            zhangsan    2022-06-04      order
            zhangsan    2022-06-03      order
            zhangsan    2022-06-02      order
            zhangsan    2022-06-01      order
    
            1d:
            2022-06-08  1   1
            2022-06-07  1   1
            2022-06-06  1   1
            2022-06-05  1   1
            2022-06-04  1   1
            2022-06-03  1   1
            2022-06-02  1   1
            2022-06-01  1   1
    
            nd(7d):
            2022-06-(02~08)  sum(order_id)7   sum(user_id)7
    
            dws层表的字段在预统计时,如果字段可以跨越天,那么就不能在每天中统计
            因为最终统计需要指定的字段,但是提前聚合不能对这个字段做统计,为了避免数据丢失,需要在我们的表中增加这个字段,而不是统计这个字段
    
     */
    DROP TABLE IF EXISTS dws_order_stats_by_tm_1d_a;
    CREATE EXTERNAL TABLE dws_order_stats_by_tm_1d_a
    (
        `tm_id`                   STRING COMMENT '品牌ID',
        `tm_name`                 STRING COMMENT '品牌名称',
        `user_id`                 BIGINT COMMENT '用户ID',
        `order_count_1d`          BIGINT COMMENT '下单数'
    ) COMMENT '各品牌商品最近1天下单统计'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_order_stats_by_tm_1d_a/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    insert overwrite table dws_order_stats_by_tm_1d_a partition (dt = '2022-06-08')
    select
        tm_id,
        tm_name,
        user_id,
        count(distinct order_id)
    from (
        select
            order_id,
            sku_id,
            user_id
        from dwd_trade_order_detail_inc
        where dt = '2022-06-08'
    ) od
    left join (
        select
            id,
            tm_id,
            tm_name
        from dim_sku_full
        where dt = '2022-06-08'
    ) sku on od.sku_id = sku.id
    group by user_id, tm_id, tm_name;
    
    select
        '2022-06-08',
        1,
        tm_id,
        tm_name,
        sum(order_count_1d),
        count(user_id)
    from dws_order_stats_by_tm_1d_a
    where dt = '2022-06-08'
    group by tm_id, tm_name;
    
    -- dws层设计目的就是简化计算,提前进行预聚合的操作
        -- 底层实现依然是将数据写入文件,再读取文件,性能一定会受到影响
        -- 如果表的设计可以在多个地方使用,那么就可以提高效率
    
    DROP TABLE IF EXISTS dws_order_stats_by_tm_1d_a;
    CREATE EXTERNAL TABLE dws_order_stats_by_tm_1d_a
    (
        `tm_id`                   STRING COMMENT '品牌ID',
        `tm_name`                 STRING COMMENT '品牌名称',
        `user_id`                 BIGINT COMMENT '用户ID',
        `order_count_1d`          BIGINT COMMENT '下单数'
    ) COMMENT '各品牌商品最近1天下单统计'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_order_stats_by_tm_1d_a/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    DROP TABLE IF EXISTS dws_order_stats_by_category_1d_a;
    CREATE EXTERNAL TABLE dws_order_stats_by_category_1d_a
    (
        `category1_id`                   STRING COMMENT '品牌ID',
        `category1_name`                 STRING COMMENT '品牌名称',
        `user_id`                 BIGINT COMMENT '用户ID',
        `order_count_1d`          BIGINT COMMENT '下单数'
    ) COMMENT '各品牌商品最近1天下单统计'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_order_stats_by_category_1d_a/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    DROP TABLE IF EXISTS dws_order_stats_by_sku_1d_a;
    CREATE EXTERNAL TABLE dws_order_stats_by_sku_1d_a
    (
        `sku_id`                  STRING COMMENT '品牌ID',
        `tm_id`                   STRING COMMENT '品牌ID',
        `tm_name`                 STRING COMMENT '品牌名称',
        `category1_id`                   STRING COMMENT '品牌ID',
        `category1_name`                 STRING COMMENT '品牌名称',
        `user_id`                 BIGINT COMMENT '用户ID',
        `order_count_1d`          BIGINT COMMENT '下单数'
    ) COMMENT '各品牌商品最近1天下单统计'
        PARTITIONED BY (`dt` STRING)
        STORED AS ORC
        LOCATION '/warehouse/gmall/dws/dws_order_stats_by_sku_1d_a/'
        TBLPROPERTIES ('orc.compress' = 'snappy');
    
    -- ADS层
        -- Application Data Service
            -- 统计结果数据量比较少,所以建表语句没有分区
            -- 统计结果为最终的结果,无需进一步的分析,所以无需列式存储和snappy压缩
            -- 因为存储的数据结果需要同步到MySQL给第三方可视化平台使用,所以一般采用tsv格式(行式存储)
            -- 表的字段不需要很多,满足客户需求即可
    
    -- 各渠道流量统计
        -- 数据源:dws_traffic_session_page_view_1d
        -- 建表语句:
    DROP TABLE IF EXISTS ads_traffic_stats_by_channel;
    CREATE EXTERNAL TABLE ads_traffic_stats_by_channel
    (
        `dt`               STRING COMMENT '统计日期',
        `recent_days`      BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
        `channel`          STRING COMMENT '渠道',
        `uv_count`         BIGINT COMMENT '访客人数',
        `avg_duration_sec` BIGINT COMMENT '会话平均停留时长,单位为秒',
        `avg_page_count`   BIGINT COMMENT '会话平均浏览页面数',
        `sv_count`         BIGINT COMMENT '会话数',
        `bounce_rate`      DECIMAL(16, 2) COMMENT '跳出率'
    ) COMMENT '各渠道流量统计'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_traffic_stats_by_channel/';
    
    insert overwrite table ads_traffic_stats_by_channel
    select *
    from ads_traffic_stats_by_channel
    union
    select * from (
        -- 最近1天
        select
            '2022-06-08',
            1,
            channel,
            count(distinct mid_id),
            avg(during_time_1d),
            avg(page_count_1d/1000),
            count(session_id),
        --     count(if(page_count_1d = 1, session_id, null)) / count(session_id)
            sum(if(page_count_1d = 1, 1, 0)) / count(session_id)
        from dws_traffic_session_page_view_1d
        where dt = '2022-06-08'
        group by channel
        union all
        -- 最近7天
        select
            '2022-06-08',
            7,
            channel,
            count(distinct mid_id),
            avg(during_time_1d),
            avg(page_count_1d/1000),
            count(session_id),
        --     count(if(page_count_1d = 1, session_id, null)) / count(session_id)
            sum(if(page_count_1d = 1, 1, 0)) / count(session_id)
        from dws_traffic_session_page_view_1d
        where dt >= date_sub('2022-06-08', 6) and dt <= '2022-06-08'
        group by channel
        union all
        -- 最近30天
        select
            '2022-06-08',
            30,
            channel,
            count(distinct mid_id),
            avg(during_time_1d),
            avg(page_count_1d/1000),
            count(session_id),
        --     count(if(page_count_1d = 1, session_id, null)) / count(session_id)
            sum(if(page_count_1d = 1, 1, 0)) / count(session_id)
        from dws_traffic_session_page_view_1d
        where dt >= date_sub('2022-06-08', 29) and dt <= '2022-06-08'
        group by channel
    ) t;
    
    -- 炸裂函数
        -- 1. 将最大范围的数据获取到
        -- 2. 将数据炸裂成多条数据,具体的条数取决于数据应用场景,而且需要给不同的场景增加标记
        -- 3. 将炸裂后的数据根据条件进行筛选过滤
        -- 4. 根据数据增加的标记,对数据进行分组聚合
    insert overwrite table ads_traffic_stats_by_channel
    select *
    from ads_traffic_stats_by_channel
    union
    select
            '2022-06-08',
            days,
            channel,
            count(distinct mid_id),
            avg(during_time_1d),
            avg(page_count_1d/1000),
            count(session_id),
            sum(if(page_count_1d = 1, 1, 0)) / count(session_id)
        from dws_traffic_session_page_view_1d lateral view explode(array(1, 7, 30)) tmp as days
        where dt >= date_sub('2022-06-08', days - 1) and dt <= '2022-06-08'
        group by channel, days;
    
    -- 路径分析
        -- 数据源:dwd_traffic_page_view_inc
        -- 建表语句
    DROP TABLE IF EXISTS ads_page_path;
    CREATE EXTERNAL TABLE ads_page_path
    (
        `dt`          STRING COMMENT '统计日期',
        `source`      STRING COMMENT '跳转起始页面ID',
        `target`      STRING COMMENT '跳转终到页面ID',
        `path_count`  BIGINT COMMENT '跳转次数'
    ) COMMENT '页面浏览路径分析'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_page_path/';
    
    -- 问题
        -- 1. 桑基图(Sankey)不允许出现环状图形
            -- 在页面前增加流程标记,区分页面跳转顺序
        -- 2. 需要统计页面离开的情况
            -- 2.1 当前统计的是页面路径跳转,前提条件是同一个会话
            -- 2.2 在同一个会话中给每一个页面额外增加一个标记,用于表示跳转后的页面,如果跳转后的页面为null,表示离开
    /*
                                          source     target      num
            zhangsan    AAAA    null      home1      list2        1
            zhangsan    AAAA    home1     list2      detail3      2
            zhangsan    AAAA    list2     detail3    cart4        3
            zhangsan    AAAA    detail3   cart4      login5       4
            zhangsan    AAAA    cart4     login5     cart6        5
            zhangsan    AAAA    login5    cart6      order7       6
            zhangsan    AAAA    cart6     order7     payment8     7
            zhangsan    AAAA    order7    payment8   out9         8
     */
    insert overwrite table ads_page_path
    select * from ads_page_path
    union
    select
        '2022-06-08',
        last_page_id source,
        page_id target,
        count(*) path_count
    from dwd_traffic_page_view_inc
    where dt = '2022-06-08'
    group by last_page_id, page_id;
    -------------------------------------------------------
    insert overwrite table ads_page_path
    select * from ads_page_path
    union
    select
        '2022-06-08',
        source,
        target,
        count(*)
    from (
        select
            concat('step-', rn, ':', source) source,
            concat('step-', (rn+1), ':', target) target
        from (
            select
                page_id source,
                -- 开窗函数
                lead(page_id, 1, 'out') over (partition by session_id order by view_time) target,
                row_number() over (partition by session_id order by view_time) rn
            from dwd_traffic_page_view_inc
            where dt = '2022-06-08'
        ) t1
    ) t group by source, target;
    
    -- 用户变动统计
    /*
        流失用户数量:2022-06-08(1)
            zhangsan: 08 07 06 05 04 03 02 01(login) 31
            lisi    : 08 07 06 05 04 03 02(login) 01 31
            wangwu  : 08 07 06 05 04 03 02 01 31(login)
            逻辑:用户的末次登录时间是7天前当天 = 8 - 7
        回流用户数:2022-06-08(2)
            zhangsan: 08(login) 07 06 05 04 03 02 01(login) 31
            lisi    : 08 07 06 05 04 03 02(login) 01 31
            wangwu  : 08(login) 07 06 05 04 03 02 01 31(login)
            zhaoliu : 08(login) 07 06 05 04 03 02 01 31 30(login)
            逻辑:今天登录 & 上一次登录时间为7天前 < 8 - 7
                上一次登录其实就是昨天统计的末次登录
     */
    
    DROP TABLE IF EXISTS ads_user_change;
    CREATE EXTERNAL TABLE ads_user_change
    (
        `dt`               STRING COMMENT '统计日期',
        `user_churn_count` BIGINT COMMENT '流失用户数',
        `user_back_count`  BIGINT COMMENT '回流用户数'
    ) COMMENT '用户变动统计'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_user_change/';
    
    -- 统计日期和业务日期的区别
        -- 统计日期(dt):数据在哪一天统计的
    -- 8号统计的,1号登录的
    insert overwrite table ads_user_change
    select * from ads_user_change
    union
    select
        '2022-06-08',
        user_churn_count,
        user_back_count
    from (
        select
            1 a,
            count(*) user_churn_count
        from dws_user_user_login_td
        where dt = '2022-06-08'
        and login_date_last = date_sub('2022-06-08', 7)
    ) churn
    join (
        select
            1 b,
            count(*) user_back_count
        from (
            select
                user_id,
                login_date_last
            from dws_user_user_login_td
            where dt = '2022-06-08'
            and login_date_last = '2022-06-08'
        ) new
        join (
            select
                user_id,
                login_date_last
            from dws_user_user_login_td
            where dt = date_sub('2022-06-08', 1)
        ) old on new.user_id = old.user_id
        where datediff(new.login_date_last, old.login_date_last) > 7
    ) back on churn.a = back.b;
    
    -- 用户留存率
    /*
            2022-06-08
                zhangsan  reg
                lisi      reg
                wangwu    reg
            2022-06-09 (1日留存率 1/3 33.3%)
                zhangsan  login
                zhaoliu   login
            2022-06-10 (2日留存率 2/3 66.6%)
                zhangsan  login
                lisi      login
                zhaoliu   login
            2022-06-11 (3日留存率 3/3 100%)
                zhangsan  login
                lisi      login
                zhaoliu   login
            ...
    
            06-xx(login) / 06-08(reg)
            ---------------------------------------------------
            2022-06-08(1日留存率 100%; 2日留存率 100%; 3日留存率 0%)
                zhangsan  login
                lisi      login
            2022-06-07
                zhansan   reg
            2022-06-06
                lisi      reg
            2022-06-05
                wangwu    reg
                zhaoliu   reg
    
            规律:
                获取1天前注册用户数量 + 获取1天前注册且当天登录用户数量
                获取2天前注册用户数量 + 获取2天前注册且当天登录用户数量
                获取3天前注册用户数量 + 获取3天前注册且当天登录用户数量
            ...
            用户登录历史至今表(td)
                -- user_id + first_date + last_date
     */
    DROP TABLE IF EXISTS ads_user_retention;
    CREATE EXTERNAL TABLE ads_user_retention
    (
        `dt`              STRING COMMENT '统计日期',
        `create_date`     STRING COMMENT '用户新增日期',
        `retention_day`   INT COMMENT '截至当前日期留存天数',
        `retention_count` BIGINT COMMENT '留存用户数量',
        `new_user_count`  BIGINT COMMENT '新增用户数量',
        `retention_rate`  DECIMAL(16, 2) COMMENT '留存率'
    ) COMMENT '用户留存率'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_user_retention/';
    
    -- 1日留存率
    select
        '2022-06-08',
        date_sub('2022-06-08', 1),
        1,
        sum(if(login_date_last = '2022-06-08', 1, 0)) retention_count,
        count(*) new_user_count,
        sum(if(login_date_last = '2022-06-08', 1, 0)) / count(*) * 100
    from dws_user_user_login_td
    where dt = '2022-06-08'
    and login_date_first = date_sub('2022-06-08', 1);
    
    -- 2日留存率
    select
        '2022-06-08',
        date_sub('2022-06-08', 2),
        2,
        sum(if(login_date_last = '2022-06-08', 1, 0)) retention_count,
        count(*) new_user_count,
        sum(if(login_date_last = '2022-06-08', 1, 0)) / count(*) * 100
    from dws_user_user_login_td
    where dt = '2022-06-08'
    and login_date_first = date_sub('2022-06-08', 2);
    
    -- 3日留存率
    select
        '2022-06-08',
        date_sub('2022-06-08', 3),
        3,
        sum(if(login_date_last = '2022-06-08', 1, 0)) retention_count,
        count(*) new_user_count,
        sum(if(login_date_last = '2022-06-08', 1, 0)) / count(*) * 100
    from dws_user_user_login_td
    where dt = '2022-06-08'
    and login_date_first = date_sub('2022-06-08', 3);
    ------------------------------------------------------------------
    insert overwrite table ads_user_retention
    select * from ads_user_retention
    union
    select
        '2022-06-08',
        login_date_first,
        datediff('2022-06-08', login_date_first),
        sum(if(login_date_last = '2022-06-08', 1, 0)) retention_count,
        count(*) new_user_count,
        sum(if(login_date_last = '2022-06-08', 1, 0)) / count(*) * 100
    from dws_user_user_login_td
    where dt = '2022-06-08'
    and login_date_first >= date_sub('2022-06-08', 7) and login_date_first < '2022-06-08'
    group by login_date_first;
    
    -- 用户新增活跃统计
    DROP TABLE IF EXISTS ads_user_stats;
    CREATE EXTERNAL TABLE ads_user_stats
    (
        `dt`                STRING COMMENT '统计日期',
        `recent_days`       BIGINT COMMENT '最近n日,1:最近1日,7:最近7日,30:最近30日',
        `new_user_count`    BIGINT COMMENT '新增用户数',
        `active_user_count` BIGINT COMMENT '活跃用户数'
    ) COMMENT '用户新增活跃统计'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_user_stats/';
    
    insert overwrite table ads_user_stats
    select * from ads_user_stats
    union
    select * from (
        -- 最近1日
        select
            '2022-06-08',
            1,
            sum(if(login_date_first = '2022-06-08', 1, 0)) new_user_count,
            count(*) active_user_count
        from dws_user_user_login_td
        where dt = '2022-06-08'
        and login_date_last = date_sub('2022-06-08', 1)
        union all
        -- 最近7日
        select
            '2022-06-08',
            7,
            sum(if(login_date_first >= date_sub('2022-06-08', 6), 1, 0)) new_user_count,
            count(*) active_user_count
        from dws_user_user_login_td
        where dt = '2022-06-08'
        and login_date_last >= date_sub('2022-06-08', 6) and  login_date_last <= '2022-06-08'
        union all
        -- 最近30日
        select
            '2022-06-08',
            30,
            sum(if(login_date_first >= date_sub('2022-06-08', 29), 1, 0)) new_user_count,
            count(*) active_user_count
        from dws_user_user_login_td
        where dt = '2022-06-08'
        and login_date_last >= date_sub('2022-06-08', 29) and  login_date_last <= '2022-06-08'
    ) t;
    
    -- 炸裂优化
    insert overwrite table ads_user_stats
    select * from ads_user_stats
    union
    select
        '2022-06-08',
        days,
        sum(if(login_date_first >= date_sub('2022-06-08', days-1), 1, 0)) new_user_count,
        count(*) active_user_count
    from dws_user_user_login_td lateral view explode(array(1, 7, 30)) tmp as days
    where dt = '2022-06-08'
    and login_date_last >= date_sub('2022-06-08', days-1) and  login_date_last <= '2022-06-08'
    group by days;
    
    -- 用户行为漏斗分析
    DROP TABLE IF EXISTS ads_user_action;
    CREATE EXTERNAL TABLE ads_user_action
    (
        `dt`                STRING COMMENT '统计日期',
        `home_count`        BIGINT COMMENT '浏览首页人数',
        `good_detail_count` BIGINT COMMENT '浏览商品详情页人数',
        `cart_count`        BIGINT COMMENT '加购人数',
        `order_count`       BIGINT COMMENT '下单人数',
        `payment_count`     BIGINT COMMENT '支付人数'
    ) COMMENT '用户行为漏斗分析'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_user_action/';
    /*
            dwd
                zhangsan home
                zhangsan home
                zhangsan home
            dws
                zhangsan home 3
                lisi     home 3
     */
     insert overwrite table ads_user_action
     select * from ads_user_action
     union
     select * from (
        select
             '2022-06-08'               ,--STRING COMMENT '统计日期',
            `home_count`        ,--BIGINT COMMENT '浏览首页人数',
            `good_detail_count` ,--BIGINT COMMENT '浏览商品详情页人数',
            `cart_count`        ,--BIGINT COMMENT '加购人数',
            `order_count`       ,--BIGINT COMMENT '下单人数',
            `payment_count`      --BIGINT COMMENT '支付人数'
         from (
            select
                1 a,
                sum(if(page_id = 'home'), 1, 0) home_count,
                sum(if(page_id = 'good_detail'), 1, 0) good_detail_count
            from dws_traffic_page_visitor_page_view_1d
            where dt = '2022-06-08'
            and (page_id = 'home' or page_id = 'good_detail')
        ) pv
        join (
            select
                1 b,
                count(user_id) cart_count
            from dws_trade_user_cart_add_1d
            where dt = '2022-06-08'
         ) cart on pv.a = cart.b
         join (
            select
                1 c,
                count(user_id) order_count
            from dws_trade_user_order_1d
            where dt = '2022-06-08'
         ) oi on cart.b = oi.c
         join (
             select
                1 d,
                count(user_id) payment_count
            from dws_trade_user_payment_1d
            where dt = '2022-06-08'
         ) pay on oi.c = pay.d
    ) t;
    
     -- 新增下单用户统计
     DROP TABLE IF EXISTS ads_new_order_user_stats;
    CREATE EXTERNAL TABLE ads_new_order_user_stats
    (
        `dt`                   STRING COMMENT '统计日期',
        `recent_days`          BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
        `new_order_user_count` BIGINT COMMENT '新增下单人数'
    ) COMMENT '新增下单用户统计'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_new_order_user_stats/';
    
    insert overwrite table ads_new_order_user_stats
    select * from ads_new_order_user_stats
    union
    select * from (
        -- 最近1天
        select
            '2022-06-08',
            1,
            count(*) new_order_user_count
        from dws_trade_user_order_td
        where dt = '2022-06-08'
        and order_date_first = '2022-06-08'
        union all
        -- 最近7天
        select
            '2022-06-08',
            7,
            count(user_id) new_order_user_count
        from dws_trade_user_order_td
        where dt = '2022-06-08'
        and order_date_first >= date_sub('2022-06-08', 6) and order_date_first <= '2022-06-08'
        union all
        -- 最近30天
        select
            '2022-06-08',
            30,
            count(user_id) new_order_user_count
        from dws_trade_user_order_td
        where dt = '2022-06-08'
        and order_date_first >= date_sub('2022-06-08', 29) and order_date_first <= '2022-06-08'
    ) t;
    
    -- 优化版
    insert overwrite table ads_new_order_user_stats
    select * from ads_new_order_user_stats
    union
    select
        '2022-06-08',
        days,
        count(user_id) new_order_user_count
    from dws_trade_user_order_td lateral view explode(array(1, 7, 30)) tmp as days
    where dt = '2022-06-08'
    and order_date_first >= date_sub('2022-06-08', days-1) and order_date_first <= '2022-06-08'
    group by days;
    
    -- 最近7日内连续3日下单用户数
        -- 数据源:dws_trade_user_order_1d
    /*
            数据的规律:
                1. 连续三天的基本条件:数据量 >= 3
                2. 连续的第三条数据的时间减去当前时间 = 2
                3. 一个用户可能会重复出现连续3天,所以统计时需要去重
    
            zhangsan(1)
                2022-06-02 order 2022-06-04 → 2
                2022-06-03 order 2022-06-06 → 3
                2022-06-04 order 2022-06-07 → 3
                2022-06-06 order 2022-06-08 → 2
                2022-06-07 order 9999-12-31 → N
                2022-06-08 order 9999-12-31 → N
            lisi(1)
                2022-06-02 order 2022-06-04 → 2
                2022-06-03 order 2022-06-05 → 2
                2022-06-04 order 2022-06-07 → 3
                2022-06-05 order 2022-06-08 → 3
                2022-06-07 order 9999-12-31 → N
                2022-06-08 order 9999-12-31 → N
            wangwu(0)
                2022-06-02 order 2022-06-05 → 3
                2022-06-03 order 2022-06-06 → 3
                2022-06-05 order 2022-06-08 → 3
                2022-06-06 order 9999-12-31 → N
                2022-06-08 order 9999-12-31 → N
     */
    DROP TABLE IF EXISTS ads_order_continuously_user_count;
    CREATE EXTERNAL TABLE ads_order_continuously_user_count
    (
        `dt`                            STRING COMMENT '统计日期',
        `recent_days`                   BIGINT COMMENT '最近天数,7:最近7天',
        `order_continuously_user_count` BIGINT COMMENT '连续3日下单用户数'
    ) COMMENT '最近7日内连续3日下单用户数统计'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_order_continuously_user_count/';
    
    insert overwrite table ads_order_continuously_user_count
    select * from ads_order_continuously_user_count
    union
    select
        '2022-06-08',
        7,
        count(distinct user_id)
    from (
        select
            user_id,
            datediff(lead(dt, 2, '9999-12-31') over (partition by user_id order by dt), dt) diff
        from dws_trade_user_order_1d
        where dt >= date_sub('2022-06-08', 6) and dt <= '2022-06-08'
    ) t where diff = 2;
    
    -- 最近30日各品牌复购率
        -- 复购率
        -- 衍生指标(比例)
            -- N派生指标
                -- 重复购买人数(下单(次数 > 1)人数) / 购买人数(下单人数)
        -- 数据来源
            -- DWS(dws_trade_user_sku_order_1d) (dws_trade_user_sku_order_nd)
            -- DWD(下单) + DIM(SKU)
            -- ODS(X)
    
    DROP TABLE IF EXISTS ads_repeat_purchase_by_tm;
    CREATE EXTERNAL TABLE ads_repeat_purchase_by_tm
    (
        `dt`                  STRING COMMENT '统计日期',
        `recent_days`       BIGINT COMMENT '最近天数,30:最近30天',
        `tm_id`              STRING COMMENT '品牌ID',
        `tm_name`            STRING COMMENT '品牌名称',
        `order_repeat_rate` DECIMAL(16, 2) COMMENT '复购率'
    ) COMMENT '最近30日各品牌复购率统计'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_repeat_purchase_by_tm/';
    
    /*
              user       tm       sku    count
            zhangsan    华为      手环      100
            zhangsan    华为      手机      200
     */
    
    -- 粒度的变化
        -- 数据源粒度:user + sku
        -- 统计粒度:sku
            -- 此时对另外一个粒度的数量统计不需要去重操作
    
        -- tm > sku
        -- 数据源粒度:user + sku
        -- 统计粒度:user + tm
        -- 如果粒度变粗(sku -> tm),那么数据就需要进一步聚合
    
        -- 数据源粒度:user + sku
        -- 统计粒度:tm
    
    -- nd表的问题
        -- nd表计算时可能出现的问题:30天内有数据,7天内没有数据,但是7天和30天会融合成一条
    insert overwrite table ads_repeat_purchase_by_tm
    select * from ads_repeat_purchase_by_tm
    union
    select
        '2022-06-08',
        30,
        tm_id,
        tm_name,
        sum(if(order_count > 1, 1, 0)) / count(user_id) * 100
    from (
        select
            user_id,
            tm_id,
            tm_name,
            sum(order_count_30d) order_count -- 某一个用户在某一个品牌下单多少次
        from dws_trade_user_sku_order_nd
        where dt = '2022-06-08'
        group by user_id, tm_id, tm_name
    ) t
    group by tm_id, tm_name;
    
    -- 各品牌商品下单统计
        -- DWD + DIM -> 1d
        -- 数据源:dws_trade_user_sku_order_1d dws_trade_user_sku_order_nd
    DROP TABLE IF EXISTS ads_order_stats_by_tm;
    CREATE EXTERNAL TABLE ads_order_stats_by_tm
    (
        `dt`                      STRING COMMENT '统计日期',
        `recent_days`             BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
        `tm_id`                   STRING COMMENT '品牌ID',
        `tm_name`                 STRING COMMENT '品牌名称',
        `order_count`             BIGINT COMMENT '下单数',
        `order_user_count`        BIGINT COMMENT '下单人数'
    ) COMMENT '各品牌商品下单统计'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_order_stats_by_tm/';
    
    -- 最近1天
        -- 数据源粒度:user + sku
        -- 统计粒度:sku
            -- user数量的统计不需要去重
        -- 统计粒度:tm
    insert overwrite table ads_order_stats_by_tm
    select * from ads_order_stats_by_tm
    union
    select * from (
        select
            '2022-06-08',
            1,
            tm_id,
            tm_name,
            sum(order_count_1d),
            count(distinct user_id)
        from dws_trade_user_sku_order_1d
        where dt = '2022-06-08'
        group by tm_id, tm_name
        union all
        -- 最近7天
        select
            '2022-06-08',
            7,
            tm_id,
            tm_name,
            sum(order_count_7d),
            count(distinct user_id)
        from dws_trade_user_sku_order_nd
        where dt = '2022-06-08'
        and order_count_7d > 0
        group by tm_id, tm_name
        union all
        -- 最近30天
        select
            '2022-06-08',
            30,
            tm_id,
            tm_name,
            sum(order_count_30d),
            count(distinct user_id)
        from dws_trade_user_sku_order_nd
        where dt = '2022-06-08'
        and order_count_30d > 0
        group by tm_id, tm_name
    ) t;
    
    insert overwrite table ads_order_stats_by_tm
    select * from ads_order_stats_by_tm
    union
    select * from (
        select '2022-06-08',
                          1,
                          tm_id,
                          tm_name,
                          sum(order_count_1d),
                          count(distinct user_id)
                   from dws_trade_user_sku_order_1d
                   where dt = '2022-06-08'
                   group by tm_id, tm_name
        union all
        select
    '2022-06-08',
              days,
              tm_id,
              tm_name,
              sum(order_count),
              count(distinct user_id)
               from (
                     select
                         days,
                         tm_id,
                         tm_name,
                         user_id,
                         if(days = 7, order_count_7d, order_count_30d) order_count
                     from dws_trade_user_sku_order_nd lateral view explode(array(7, 30)) tmp as days
                     where dt = '2022-06-08') t
               where order_count > 0
               group by days, tm_id, tm_name
    ) t;
    
    -- 各品类商品下单统计
    DROP TABLE IF EXISTS ads_order_stats_by_cate;
    CREATE EXTERNAL TABLE ads_order_stats_by_cate
    (
        `dt`                      STRING COMMENT '统计日期',
        `recent_days`             BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
        `category1_id`            STRING COMMENT '一级品类ID',
        `category1_name`          STRING COMMENT '一级品类名称',
        `category2_id`            STRING COMMENT '二级品类ID',
        `category2_name`          STRING COMMENT '二级品类名称',
        `category3_id`            STRING COMMENT '三级品类ID',
        `category3_name`          STRING COMMENT '三级品类名称',
        `order_count`             BIGINT COMMENT '下单数',
        `order_user_count`        BIGINT COMMENT '下单人数'
    ) COMMENT '各品类商品下单统计'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_order_stats_by_cate/';
    
    insert overwrite table ads_order_stats_by_cate
    select * from ads_order_stats_by_cate
    union
    select * from (
        select
            '2022-06-08',
            1,
            category1_id,
            category1_name,
            category2_id,
            category2_name,
            category3_id,
            category3_name,
            sum(order_count_1d),
            count(distinct user_id)
       from dws_trade_user_sku_order_1d
       where dt = '2022-06-08'
       group by
            category1_id,
            category1_name,
            category2_id,
            category2_name,
            category3_id
        union all
        select
            '2022-06-08',
            days,
            category1_id,
            category1_name,
            category2_id,
            category2_name,
            category3_id,
            category3_name,
            sum(order_count),
            count(distinct user_id)
            from (
                 select
                     days,
                     category1_id,
                     category1_name,
                     category2_id,
                     category2_name,
                     category3_id,
                     category3_name,
                     user_id,
                     if(days = 7, order_count_7d, order_count_30d) order_count
                 from dws_trade_user_sku_order_nd lateral view explode(array(7, 30)) tmp as days
                 where dt = '2022-06-08') t
            where order_count > 0
            group by
                days,
                category1_id,
                category1_name,
                category2_id,
                category2_name,
                category3_id,
                category3_name
    ) t;
    
    -- 各品类商品购物车存量Top3
        -- 各品类商品
        -- 购物车存量
            -- 周期快照事实表
        -- Top3
        -- 组内排序取TopN
            -- 实现思路
                -- 1. 统计粒度 + 维度 -> 统计销量
                -- 2. 将相同的统计粒度数据分在一个组中(数据不会减少 -> 开窗)
                -- 3. 将组内的统计结果排序(开窗带排序)
                -- 4. 将组内排序结果取前N条(row_number <= N)
    
    /*
            手机  小米13    300
            手机  苹果13    200
            手环  小米9     100
     */
    
    DROP TABLE IF EXISTS ads_sku_cart_num_top3_by_cate;
    CREATE EXTERNAL TABLE ads_sku_cart_num_top3_by_cate
    (
        `dt`             STRING COMMENT '统计日期',
        `category1_id`   STRING COMMENT '一级品类ID',
        `category1_name` STRING COMMENT '一级品类名称',
        `category2_id`   STRING COMMENT '二级品类ID',
        `category2_name` STRING COMMENT '二级品类名称',
        `category3_id`   STRING COMMENT '三级品类ID',
        `category3_name` STRING COMMENT '三级品类名称',
        `sku_id`         STRING COMMENT 'SKU_ID',
        `sku_name`       STRING COMMENT 'SKU名称',
        `cart_num`       BIGINT COMMENT '购物车中商品数量',
        `rk`             BIGINT COMMENT '排名'
    ) COMMENT '各品类商品购物车存量Top3'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_sku_cart_num_top3_by_cate/';
    
    insert overwrite table ads_sku_cart_num_top3_by_cate
    select * from ads_sku_cart_num_top3_by_cate
    union
    select
        '2022-06-08',
        category1_id,
        category1_name,
        category2_id,
        category2_name,
        category3_id,
        category3_name,
        sku_id,
        sku_name,
        cart_num,
        rk
    from (
        select
            category1_id,
            category1_name,
            category2_id,
            category2_name,
            category3_id,
            category3_name,
            sku_id,
            sku_name,
            cart_num,
            rank() over (partition by category1_id, category2_id, category3_id order by cart_num desc) rk
        from (
            select
                category1_id,
                category1_name,
                category2_id,
                category2_name,
                category3_id,
                category3_name,
                sku_id,
                sku_name,
                cart_num
            from (
                select
                    sku_id,
                    sum(sku_num) cart_num
                from dwd_trade_cart_full
                where dt = '2022-06-08'
                group by sku_id
            ) cart
            left join (
                select
                    id,
                    sku_name,
                    category1_id,
                    category1_name,
                    category2_id,
                    category2_name,
                    category3_id,
                    category3_name
                from dim_sku_full
                where dt = '2022-06-08'
            ) sku on cart.sku_id = sku.id
        ) t
    ) t1 where rk <= 3;
    
    -- 各品牌商品收藏次数Top3
    DROP TABLE IF EXISTS ads_sku_favor_count_top3_by_tm;
    CREATE EXTERNAL TABLE ads_sku_favor_count_top3_by_tm
    (
        `dt`          STRING COMMENT '统计日期',
        `tm_id`       STRING COMMENT '品牌ID',
        `tm_name`     STRING COMMENT '品牌名称',
        `sku_id`      STRING COMMENT 'SKU_ID',
        `sku_name`    STRING COMMENT 'SKU名称',
        `favor_count` BIGINT COMMENT '被收藏次数',
        `rk`          BIGINT COMMENT '排名'
    ) COMMENT '各品牌商品收藏次数Top3'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_sku_favor_count_top3_by_tm/';
    
    -- 实现思路
        -- 1. (品牌 + 商品) -> 统计收藏次数
        -- 2. 按照品牌分组
        -- 3. 按照次数进行排序(降序)
        -- 4. 取排序后的前3名
    -- 粒度的变化
        -- 数据源粒度:sku
        -- 统计粒度:(tm) + sku
    
    insert overwrite table ads_sku_favor_count_top3_by_tm
    select * from ads_sku_favor_count_top3_by_tm
    union
    select
        '2022-06-08',
        tm_id,
        tm_name,
        sku_id,
        sku_name,
        favor_add_count_1d,
        rk
    from (
        select
            sku_id,
            sku_name,
            tm_id,
            tm_name,
            favor_add_count_1d,
            rank() over (partition by tm_id order by favor_add_count_1d desc) rk
        from dws_interaction_sku_favor_add_1d
        where dt = '2022-06-08'
    ) t where rk <= 3;
    
    -- 下单到支付时间间隔平均值
    DROP TABLE IF EXISTS ads_order_to_pay_interval_avg;
    CREATE EXTERNAL TABLE ads_order_to_pay_interval_avg
    (
        `dt`                        STRING COMMENT '统计日期',
        `order_to_pay_interval_avg` BIGINT COMMENT '下单到支付时间间隔平均值,单位为秒'
    ) COMMENT '下单到支付时间间隔平均值统计'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_order_to_pay_interval_avg/';
    
    -- 用户年龄平均值:avg(age)
    -- 订单下单到支付时间间隔平均值:avg(datediff(支付时间, 下单时间))
    -- 累积快照事实表
        -- 1. 时间差问题
            -- datediff:用于天的时间差,不能用于时分秒的差值计算
            -- 时间戳相减 sub -> (string -> long) - (string -> long)
            -- long -> timestamp(string, date) -> date_format
        -- 2. 分区策略
            -- 事实表会以流程中最后一个行为的时间作为分区字段值(收货时间)
    insert overwrite table ads_order_to_pay_interval_avg
    select * from ads_order_to_pay_interval_avg
    union
    select
        '2022-06-08',
        avg(to_unix_timestamp(payment_time) - to_unix_timestamp(order_time))
    from dwd_trade_trade_flow_acc
    where (dt = '2022-06-08' or dt = '9999-12-31') and payment_date_id = '2022-06-08';
    
    -- 各省份交易统计
    DROP TABLE IF EXISTS ads_order_by_province;
    CREATE EXTERNAL TABLE ads_order_by_province
    (
        `dt`                 STRING COMMENT '统计日期',
        `recent_days`        BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
        `province_id`        STRING COMMENT '省份ID',
        `province_name`      STRING COMMENT '省份名称',
        `area_code`          STRING COMMENT '地区编码',
        `iso_code`           STRING COMMENT '旧版国际标准地区编码,供可视化使用',
        `iso_code_3166_2`    STRING COMMENT '新版国际标准地区编码,供可视化使用',
        `order_count`        BIGINT COMMENT '订单数',
        `order_total_amount` DECIMAL(16, 2) COMMENT '订单金额'
    ) COMMENT '各省份交易统计'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_order_by_province/';
    -- 粒度没有变化
    insert overwrite table ads_order_by_province
    select * from ads_order_by_province
    union
    select
            `dt`                 ,--STRING COMMENT '统计日期',
            1        ,--BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
            `province_id`        ,--STRING COMMENT '省份ID',
            `province_name`      ,--STRING COMMENT '省份名称',
            `area_code`          ,--STRING COMMENT '地区编码',
            `iso_code`           ,--STRING COMMENT '旧版国际标准地区编码,供可视化使用',
            iso_3166_2 `iso_code_3166_2`    ,--STRING COMMENT '新版国际标准地区编码,供可视化使用',
            `order_count_1d`        ,--BIGINT COMMENT '订单数',
            `order_total_amount_1d`  --DECIMAL(16, 2) COMMENT '订单金额'
        from dws_trade_province_order_1d
        where dt = '2022-06-08'
    union -- all 报错
    select
            `dt`                 ,--STRING COMMENT '统计日期',
            days        ,--BIGINT COMMENT '最近天数,1:最近1天,7:最近7天,30:最近30天',
            `province_id`        ,--STRING COMMENT '省份ID',
            `province_name`      ,--STRING COMMENT '省份名称',
            `area_code`          ,--STRING COMMENT '地区编码',
            `iso_code`           ,--STRING COMMENT '旧版国际标准地区编码,供可视化使用',
            iso_3166_2 `iso_code_3166_2`    ,--STRING COMMENT '新版国际标准地区编码,供可视化使用',
            if(days = 7, order_count_7d, order_count_30d)        ,--BIGINT COMMENT '订单数',
            if(days = 7, order_total_amount_7d, order_total_amount_30d)  --DECIMAL(16, 2) COMMENT '订单金额'
        from dws_trade_province_order_nd lateral view explode(array(7, 30)) tmp as days
        where dt = '2022-06-08';
    
    -- 优惠券使用统计
        -- 数据源:dws_tool_user_coupon_coupon_used_1d
            -- 粒度:user + coupon
        -- 粒度:coupon
    DROP TABLE IF EXISTS ads_coupon_stats;
    CREATE EXTERNAL TABLE ads_coupon_stats
    (
        `dt`              STRING COMMENT '统计日期',
        `coupon_id`       STRING COMMENT '优惠券ID',
        `coupon_name`     STRING COMMENT '优惠券名称',
        `used_count`      BIGINT COMMENT '使用次数',
        `used_user_count` BIGINT COMMENT '使用人数'
    ) COMMENT '优惠券使用统计'
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        LOCATION '/warehouse/gmall/ads/ads_coupon_stats/';
    
    insert overwrite table ads_coupon_stats
    select * from ads_coupon_stats
    union
    select
        '2022-06-08',
        coupon_id,
        coupon_name,
        sum(used_count_1d),
        count(user_id)
    from dws_tool_user_coupon_coupon_used_1d
    where dt = '2022-06-08'
    group by coupon_id, coupon_name;
    

五、知识get

  • 维度分析

    data_dim_analysis

  • Hive中的数据转换

    hive_SerDe

  • Hive BUG

    • cbo优化会导致hive struct 结构体判空操作失效,执行计划缺少对应的 filter
    • 解决思路:set hive.cbo.enable=false;
    • 参考issue:https://issues.apache.org/jira/browse/HIVE-21778
✨ 本站由 Hugo + Stack 主题搭建 | 不忘初心,慢慢成长 ✨
使用 Hugo 构建
主题 StackJimmy 设计