求各区域热门商品Top3 - HiveSQL

  1. 背景:这是尚硅谷SparkSQL练习题,本文用HiveSQL进行了实现。

  2. 数据集:用户点击表,商品表,城市表



  3. 题目:

    ① 求每个地区点击量前三的商品;

    ② 在①的基础上,求出每个地区点击量前三的商品后,求出每个商品中的点击量前三的城市分别占本商品总点击量的百分比。

  4. 建表,导入数据

    没啥说的,建表语句直接抄过来

sql 复制代码
use atguigu;

CREATE TABLE `user_visit_action`(
  `date` string,
  `user_id` bigint,
  `session_id` string,
  `page_id` bigint,
  `action_time` string,
  `search_keyword` string,
  `click_category_id` bigint,
  `click_product_id` bigint,
  `order_category_ids` string,
  `order_product_ids` string,
  `pay_category_ids` string,
  `pay_product_ids` string,
  `city_id` bigint)
row format delimited fields terminated by '\t';

load data local inpath 'datas/user_visit_action.txt' 
into table atguigu.user_visit_action;

CREATE TABLE `product_info`(
  `product_id` bigint,
  `product_name` string,
  `extend_info` string)
row format delimited fields terminated by '\t';

load data local inpath 'datas/product_info.txt' into table atguigu.product_info;

CREATE TABLE `city_info`(
  `city_id` bigint,
  `city_name` string,
  `area` string)
row format delimited fields terminated by '\t';

load data local inpath 'datas/city_info.txt' into table atguigu.city_info;
  1. 查询

第一问:求每个地区点击量前三的商品;

分析:按 area,product_name 两个字段分组,求出点击量click_ct2,保留每个地区点击量前三的商品。

sql 复制代码
select
    area,
    product_name,
    click_ct2
from (
    select
        area,
        product_name,
        click_ct2,
        row_number() over( partition by area order by click_ct2 desc ) as rn2
    from (
        select
           area,
           product_name,
           count(*) as click_ct2
        from (
            select
               a.*,
               p.product_name,
               c.area,
               c.city_name
            from user_visit_action a
            join product_info p on a.click_product_id = p.product_id
            join city_info c on a.city_id = c.city_id
            where a.click_product_id > -1
        ) t1 
        group by area, product_name
    ) t2
) t3 
where rn2 <= 3

第二问: 在①的基础上,求出每个地区点击量前三的商品后,求每个商品中的点击量前三的城市分别占本商品总点击量的百分比。

分析:

第一问求出了每个地区、每个商品的点击量,这个点击量叫click_ct2,并取了每个地区前三名的商品。

在第二问中,可以先求出每个地区、每个商品、每个城市的点击量,这个点击量叫click_ct3,取每个地区、每个商品点击量的前三名城市。

用click_ct3/click_ct2就是每个地区、每个商品、每个城市点击率,这个点击率叫click_rate3。

click_ct3所在的临时表叫tmp1,click_ct2所在的临时表叫tmp2。

tmp1有三个维度,粒度更细,数据条数会更多,tmp2有两个维度,粒度粗,数据条数少。

无论是tmp1 join tmp2,还是tmp2 join tmp1,两种方式都可以,tmp1中不符合条件的数据会被筛掉。

之后,用concat()将每行的城市名和点击率拼接在一起,

再按地区、商品、总点击量进行分组,用collect_set()收集每组拼接的结果,

将收集的结果拼接成字符串,再转换成map。

sql 复制代码
--维度:area,city_name,product_name
--度量:点击次数
--限定:前三
with tmp1 as(
    select 
        area,
        product_name,
        city_name,
        click_ct3
    from(
        select 
            area,
            city_name,
            product_name,
            click_ct3,
            row_number()over(partition by area,product_name order by click_ct3) rn1
        from(
            select 
                area,
                city_name,
                product_name,
                count(*) click_ct3
            from(
                select
                    a.*,
                    p.product_name,
                    c.area,
                    c.city_name
                from user_visit_action a
                join product_info p on a.click_product_id = p.product_id
                join city_info c on a.city_id = c.city_id
                where a.click_product_id > -1
            )t1
            group by area,city_name,product_name
        )t2
    )t3
    where rn1<=3
    order by area,product_name,city_name,click_ct3 desc
),
--维度:area,product_name
--度量:点击次数
--限定:前三
tmp2 as(
    select
        area,
        product_name,
        click_ct2
    from (
        select
            area,
            product_name,
            click_ct2,
            row_number() over( partition by area order by click_ct2 desc ) as rn2
        from (
            select
               area,
               product_name,
               count(*) as click_ct2
            from (
                select
                   a.*,
                   p.product_name,
                   c.area,
                   c.city_name
                from user_visit_action a
                join product_info p on a.click_product_id = p.product_id
                join city_info c on a.city_id = c.city_id
                where a.click_product_id > -1
            ) t1 
            group by area, product_name
        ) t2
    ) t3 
    where rn2 <= 3
)
select 
    area,
    product_name,
    click_ct2,
    -- 按地区、商品、总点击量进行分组,用collect_set()收集每组拼接的结果,
    -- 将收集后的结果转换成map
    str_to_map(concat_ws(',',collect_set(city_rate)),',',':') city_rate3
from(
    select 
        area,
        product_name,
        click_ct2,
        click_rate,
        -- 将每行的城市名和点击率拼接在一起
        concat(city_name,':',click_rate,'%') city_rate
    from(
        select 
            tmp1.area,
            tmp1.product_name,
            tmp1.city_name,
            tmp2.click_ct2,
            round(tmp1.click_ct3*100/tmp2.click_ct2,2) click_rate
        from tmp2 
        join tmp1 on tmp2.area=tmp1.area and tmp2.product_name=tmp1.product_name
    )t1
    order by area,click_ct2 desc,click_rate desc
)t2
group by area,product_name,click_ct2
order by area,click_ct2 desc
相关推荐
starfalling10247 小时前
【hive】一种高效增量表的实现
hive
D明明就是我11 小时前
Hive 拉链表
数据仓库·hive·hadoop
嘉禾望岗50315 小时前
hive join优化和数据倾斜处理
数据仓库·hive·hadoop
yumgpkpm15 小时前
华为鲲鹏 Aarch64 环境下多 Oracle 数据库汇聚操作指南 CMP(类 Cloudera CDP 7.3)
大数据·hive·hadoop·elasticsearch·zookeeper·big data·cloudera
忧郁火龙果17 小时前
六、Hive的基本使用
数据仓库·hive·hadoop
忧郁火龙果17 小时前
五、安装配置hive
数据仓库·hive·hadoop
chad__chang1 天前
dolphinscheduler安装过程
hive·hadoop
yumgpkpm3 天前
CMP (类ClouderaCDP7.3(404次编译) )华为鲲鹏Aarch64(ARM)信创环境多个mysql数据库汇聚的操作指南
大数据·hive·hadoop·zookeeper·big data·cloudera
夫唯不争,故无尤也4 天前
Maven创建Java项目实战全流程
java·数据仓库·hive·hadoop·maven
yumgpkpm5 天前
CMP (类Cloudera) CDP7.3(400次编译)在华为鲲鹏Aarch64(ARM)信创环境中的性能测试过程及命令
大数据·hive·hadoop·python·elasticsearch·spark·cloudera