大数据技术之Hive SQL题库-中级2

本文涉及的产品
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
简介: 大数据技术之Hive SQL题库-中级2

1.9 好友关系表

1)表结构

user1_id(用户1 id)

user2_id(用户2 id)

101

1010

101

108

101

106


注:表中一行数据中的两个user_id,表示两个用户互为好友。

2)建表语句

hive>

DROP TABLE IF EXISTS friendship_info;
CREATE TABLE friendship_info(
    `user1_id` string comment '用户1id',
    `user2_id` string comment '用户2id'
) COMMENT '用户关系表'
    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';


3)数据装载

hive>

insert overwrite table friendship_info
values ('101', '1010'),
       ('101', '108'),
       ('101', '106'),
       ('101', '104'),
       ('101', '102'),
       ('102', '1010'),
       ('102', '108'),
       ('102', '106'),
       ('102', '104'),
       ('102', '102'),
       ('103', '1010'),
       ('103', '108'),
       ('103', '106'),
       ('103', '104'),
       ('103', '102'),
       ('104', '1010'),
       ('104', '108'),
       ('104', '106'),
       ('104', '104'),
       ('104', '102'),
       ('105', '1010'),
       ('105', '108'),
       ('105', '106'),
       ('105', '104'),
       ('105', '102'),
       ('106', '1010'),
       ('106', '108'),
       ('106', '106'),
       ('106', '104'),
       ('106', '102'),
       ('107', '1010'),
       ('107', '108'),
       ('107', '106'),
       ('107', '104'),
       ('107', '102'),
       ('108', '1010'),
       ('108', '108'),
       ('108', '106'),
       ('108', '104'),
       ('108', '102'),
       ('109', '1010'),
       ('109', '108'),
       ('109', '106'),
       ('109', '104'),
       ('109', '102'),
       ('1010', '1010'),
       ('1010', '108'),
       ('1010', '106'),
       ('1010', '104'),
       ('1010', '102');


1.10 收藏信息表

1)表结构

user_id(用户id)

sku_id(商品id)

create_date(收藏日期)

101

3

2021-09-23

101

12

2021-09-23

101

6

2021-09-25


2)建表语句

hive>

DROP TABLE IF EXISTS favor_info;
CREATE TABLE favor_info
(
    `user_id`     string comment '用户id',
    `sku_id`      string comment '商品id',
    `create_date` string comment '收藏日期'
) COMMENT '用户收藏表'
    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';


3)数据装载

hive>

insert overwrite table favor_info
values ('101', '3', '2021-09-23'),
       ('101', '12', '2021-09-23'),
       ('101', '6', '2021-09-25'),
       ('101', '10', '2021-09-21'),
       ('101', '5', '2021-09-25'),
       ('102', '1', '2021-09-24'),
       ('102', '2', '2021-09-24'),
       ('102', '8', '2021-09-23'),
       ('102', '12', '2021-09-22'),
       ('102', '11', '2021-09-23'),
       ('102', '9', '2021-09-25'),
       ('102', '4', '2021-09-25'),
       ('102', '6', '2021-09-23'),
       ('102', '7', '2021-09-26'),
       ('103', '8', '2021-09-24'),
       ('103', '5', '2021-09-25'),
       ('103', '6', '2021-09-26'),
       ('103', '12', '2021-09-27'),
       ('103', '7', '2021-09-25'),
       ('103', '10', '2021-09-25'),
       ('103', '4', '2021-09-24'),
       ('103', '11', '2021-09-25'),
       ('103', '3', '2021-09-27'),
       ('104', '9', '2021-09-28'),
       ('104', '7', '2021-09-28'),
       ('104', '8', '2021-09-25'),
       ('104', '3', '2021-09-28'),
       ('104', '11', '2021-09-25'),
       ('104', '6', '2021-09-25'),
       ('104', '12', '2021-09-28'),
       ('105', '8', '2021-10-08'),
       ('105', '9', '2021-10-07'),
       ('105', '7', '2021-10-07'),
       ('105', '11', '2021-10-06'),
       ('105', '5', '2021-10-07'),
       ('105', '4', '2021-10-05'),
       ('105', '10', '2021-10-07'),
       ('106', '12', '2021-10-08'),
       ('106', '1', '2021-10-08'),
       ('106', '4', '2021-10-04'),
       ('106', '5', '2021-10-08'),
       ('106', '2', '2021-10-04'),
       ('106', '6', '2021-10-04'),
       ('106', '7', '2021-10-08'),
       ('107', '5', '2021-09-29'),
       ('107', '3', '2021-09-28'),
       ('107', '10', '2021-09-27'),
       ('108', '9', '2021-10-08'),
       ('108', '3', '2021-10-10'),
       ('108', '8', '2021-10-10'),
       ('108', '10', '2021-10-07'),
       ('108', '11', '2021-10-07'),
       ('109', '2', '2021-09-27'),
       ('109', '4', '2021-09-29'),
       ('109', '5', '2021-09-29'),
       ('109', '9', '2021-09-30'),
       ('109', '8', '2021-09-26'),
       ('1010', '2', '2021-09-29'),
       ('1010', '9', '2021-09-29'),
       ('1010', '1', '2021-10-01');


第2章 练习题

2.1 查询累积销量排名第二的商品

2.1.1 题目需求

查询订单明细表(order_detail)中销量(下单件数)排名第二的商品id,如果不存在返回null,如果存在多个排名第二的商品则需要全部返回。期望结果如下:

sku_id

2


2.1.2 代码实现

hive>

select sku_id
from (
         select sku_id
         from (
                  select sku_id,
                         order_num,
                         dense_rank() over (order by order_num desc) rk
                  from (
                           select sku_id,
                                  sum(sku_num) order_num
                           from order_detail
                           group by sku_id
                       ) t1
              ) t2
         where rk = 2
     ) t3
         right join --为保证,没有第二名的情况下,返回null
     (
         select 1
     ) t4; 


需要注意的几个点:


1.group by sku_id这句我一开始都没想到,因为同一个商品在同一天可能会被下单很多次,所以这里需要分组


2.dense_rank() over (order by order_num desc) rk这里我尝试写成下面这样,但是报错!说明这样写不行,我还想着把这两个select合成一个,结果也不行!所以需要在写一个select去用where筛选



3.select 1的返回结果就是1,就一条记录,这里通过和select 1进行right join来实现“如果不存在返回null,如果存在多个排名第二的商品则需要全部返回”这个效果,假如左边查询的sku_id是null,那么null和select 1去join的结果就是null,因为最终查询的是sku_id


4.下面的t1-t4我一开始是没有加的,因为我觉得都没有用到,不需要加也可以,结果报错!


查漏补缺:dense_rank() over是用来排名的,有三种排名的方式,分别是rank() over()、row_number() over()、dense_rank() over() 。


例如下面用的rank() over()函数,在列值重复的情况下,也就是score有两个65,这里两个65并列排在第3名,然后57排在第5名了,没有第4名

例如下面使用dense_rank() over函数,score有两个65,这里两个65并列排在第3名,然后57排在第4名了,跟rank() over()对比发现rank() over()只要重复了排名就会在下一个排名那里跳过去,而rank() over()不会跳,不管重复多少都会按顺序来排名,也就是不会有缺少某个排名的情况

例如下面使用row_number() over()函数,score有两个80,这里两个80分别排名为2和3名,跟上面两个对比发现,上面两个函数是有重复就并列多少名,这个函数就重复也会继续排序,很明显,这不公平哈哈


2.2 查询至少连续三天下单的用户

2.2.1 题目需求

查询订单信息表(order_info)中最少连续3天下单的用户id,期望结果如下:

user_id

10158分45秒


2.2.2 代码实现

hive> 
select distinct user_id
from (
         select user_id
         from (
                  select user_id, 
                         create_date,
                         date_sub(create_date, row_number() over (partition by user_id order by create_date)) flag
                  from (
                           select user_id,
                                  create_date
                           from order_info
                           group by user_id, create_date
                       ) t1 --同一天同一个用户可以下单多次,所以要分组 同一天可能多个用户下单,进行去重
              ) t2 -- 判断一串日期是否连续:若连续,用这个日期减去它的排名,会得到一个相同的结果
         group by user_id, flag
         having count(flag) >= 3 -- 连续下单大于等于三天
     ) t3;
骚戴解法
SELECT 
    user_id 
FROM (
    SELECT 
        user_id ,
        create_date,
        date_sub(create_date,row_number() over (partition by user_id order by create_date)) flag
    FROM (
         SELECT 
             user_id ,
             create_date 
         FROM order_info 
         GROUP by user_id,create_date 
         )t1
      )t2
GROUP by user_id,flag
HAVING  COUNT(flag) >=3;1.

骚戴理解:最里面的select的group by是为了去重,因为同一个用户同一天可能下单多次,date_sub(create_date,row_number() over (partition by user_id order by create_date)) flag这个语句最难理解,这里的date_sub函数是日期相减的意思,row_number() over (partition by user_id order by create_date)是一个开窗函数,作用就是按照user_id分组,按照create_date进行排序并且排名,拆开理解是很容易理解的,但是它是怎么实现“最少连续3天”这个效果的呢?


  select user_id, 
         create_date,
          row_number() over (partition by user_id order by create_date) rn,
         date_sub(create_date, row_number() over (partition by user_id order by create_date)) flag
  from (
           select user_id,
                  create_date
           from order_info
           group by user_id, create_date
       )t1;

这里为了更好的理解,我把它拆开并且查询出来,看看到底是什么东西?下面就是上面的hql运行的结果!下面的rn列就是一个排名


这里理解date_sub(create_date,row_number() over (partition by user_id order by create_date)) flag的核心在于要明白如果create_date是连续的,那么create_date减掉rn的值就是一样的!例如上面的101可以看出flag都是一样的。所以只要flag是相同的那么就说明create_date是连续的日期,然后再写一个select去子查询,最后通过下面两句来筛选出最少连续3天下单的用户。注意这里的分组是有flag的!


GROUP by user_id,flag

HAVING COUNT(flag) >=3


2.3 查询各品类销售商品的种类数及销量最高的商品

2.3.1 题目需求

从订单明细表(order_detail)统计各品类销售出的商品种类数累积销量最好的商品,期望结果如下:

1686553070860.png


2.3.2 代码实现

hive>

select category_id,
       category_name,
       sku_id,
       name,
       order_num,
       sku_cnt
from (
         select od.sku_id,
                sku.name,
                sku.category_id,
                cate.category_name,
                order_num,
                rank() over (partition by sku.category_id order by order_num desc) rk,
                count(od.sku_id) over (partition by sku.category_id) sku_cnt
         from (
                  select sku_id,
                         sum(sku_num) order_num
                  from order_detail
                  group by sku_id
              ) od
                  left join
              sku_info sku
              on od.sku_id = sku.sku_id
                  left join
              category_info cate
              on sku.category_id = cate.category_id
     ) t1
where rk = 1;

骚戴理解:


1.这个题目用到了sku_info表、category_info表、order_detail表


2.特别注意在多表联查的时候select后面的字段如果是在多个表里出现过的那就必须要通过表名.字段名的方式,例如od.sku_id,不然它不知道你要用哪个表的sku_id


3.这里sum(sku_num) order_num我一开始写错了,用的count函数而不是sum函数


4.rank() over (partition by sku.category_id order by order_num desc) rk这里用的rank()over(),所以会跳,具体的看上面的查漏补缺介绍


5.count( od.sku_id) over (partition by sku.category_id) sku_cnt这语句相当于下面的


select 
    count(sku_id)
from sku_info
group by category_id;

其实就是实现“统计各品类销售出的商品种类数”这个效果,这种写法很妙,特别是在group by的限制情况下使用,非常nice!

2.4 查询用户的累计消费金额及VIP等级

2.4.1 题目需求

从订单信息表(order_info)中统计每个用户截止其每个下单日期的累积消费金额,以及每个用户在其每个下单日期的VIP等级。


用户vip等级根据累积消费金额计算,计算规则如下:


设累积消费总额为X,


若0=<X<10000,则vip等级为普通会员


若10000<=X<30000,则vip等级为青铜会员


若30000<=X<50000,则vip等级为白银会员


若50000<=X<80000,则vip为黄金会员


若80000<=X<100000,则vip等级为白金会员


若X>=100000,则vip等级为钻石会员


期望结果如下:


相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps&nbsp;
目录
相关文章
|
21天前
|
存储 机器学习/深度学习 分布式计算
大数据技术——解锁数据的力量,引领未来趋势
【10月更文挑战第5天】大数据技术——解锁数据的力量,引领未来趋势
|
8天前
|
存储 分布式计算 数据可视化
大数据常用技术与工具
【10月更文挑战第16天】
40 4
|
21天前
|
存储 数据采集 监控
大数据技术:开启智能决策与创新服务的新纪元
【10月更文挑战第5天】大数据技术:开启智能决策与创新服务的新纪元
|
21天前
|
存储 分布式计算 druid
大数据-149 Apache Druid 基本介绍 技术特点 应用场景
大数据-149 Apache Druid 基本介绍 技术特点 应用场景
46 1
大数据-149 Apache Druid 基本介绍 技术特点 应用场景
|
21天前
|
存储 数据采集 分布式计算
大数据技术:开启智能时代的新引擎
【10月更文挑战第5天】大数据技术:开启智能时代的新引擎
|
21天前
|
SQL 消息中间件 分布式计算
大数据-143 - ClickHouse 集群 SQL 超详细实践记录!(一)
大数据-143 - ClickHouse 集群 SQL 超详细实践记录!(一)
53 0
|
21天前
|
SQL 大数据
大数据-143 - ClickHouse 集群 SQL 超详细实践记录!(二)
大数据-143 - ClickHouse 集群 SQL 超详细实践记录!(二)
48 0
|
21天前
|
SQL 大数据 API
大数据-132 - Flink SQL 基本介绍 与 HelloWorld案例
大数据-132 - Flink SQL 基本介绍 与 HelloWorld案例
39 0
|
22天前
|
SQL 分布式计算 大数据
大数据-97 Spark 集群 SparkSQL 原理详细解析 Broadcast Shuffle SQL解析过程(一)
大数据-97 Spark 集群 SparkSQL 原理详细解析 Broadcast Shuffle SQL解析过程(一)
33 0
|
22天前
|
SQL 分布式计算 算法
大数据-97 Spark 集群 SparkSQL 原理详细解析 Broadcast Shuffle SQL解析过程(二)
大数据-97 Spark 集群 SparkSQL 原理详细解析 Broadcast Shuffle SQL解析过程(二)
61 0