求各区域热门商品Top3 - HiveSQL

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

  2. 数据集:用户点击表,商品表,城市表
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

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

  4. 建表,导入数据
    没啥说的,建表语句直接抄过来

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,保留每个地区点击量前三的商品。

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。

--维度: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

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小刘新鲜事儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值