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

本文涉及的产品
云原生大数据计算服务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的热门话题分析
Apsara Clouder大数据专项技能认证配套课程:基于MaxCompute的热门话题分析
目录
相关文章
|
2月前
|
SQL 数据可视化 关系型数据库
MCP与PolarDB集成技术分析:降低SQL门槛与简化数据可视化流程的机制解析
阿里云PolarDB与MCP协议融合,打造“自然语言即分析”的新范式。通过云原生数据库与标准化AI接口协同,实现零代码、分钟级从数据到可视化洞察,打破技术壁垒,提升分析效率99%,推动企业数据能力普惠化。
233 3
|
6月前
|
SQL 分布式计算 大数据
大数据新视界 --大数据大厂之Hive与大数据融合:构建强大数据仓库实战指南
本文深入介绍 Hive 与大数据融合构建强大数据仓库的实战指南。涵盖 Hive 简介、优势、安装配置、数据处理、性能优化及安全管理等内容,并通过互联网广告和物流行业案例分析,展示其实际应用。具有专业性、可操作性和参考价值。
大数据新视界 --大数据大厂之Hive与大数据融合:构建强大数据仓库实战指南
|
8月前
|
SQL 分布式计算 资源调度
Dataphin功能Tips系列(48)-如何根据Hive SQL/Spark SQL的任务优先级指定YARN资源队列
如何根据Hive SQL/Spark SQL的任务优先级指定YARN资源队列
310 4
|
9月前
|
SQL 存储 关系型数据库
【SQL技术】不同数据库引擎 SQL 优化方案剖析
不同数据库系统(MySQL、PostgreSQL、Doris、Hive)的SQL优化策略。存储引擎特点、SQL执行流程及常见操作(如条件查询、排序、聚合函数)的优化方法。针对各数据库,索引使用、分区裁剪、谓词下推等技术,并提供了具体的SQL示例。通用的SQL调优技巧,如避免使用`COUNT(DISTINCT)`、减少小文件问题、慎重使用`SELECT *`等。通过合理选择和应用这些优化策略,可以显著提升数据库查询性能和系统稳定性。
382 9
|
SQL 存储 算法
比 SQL 快出数量级的大数据计算技术
SQL 是大数据计算中最常用的工具,但在实际应用中,SQL 经常跑得很慢,浪费大量硬件资源。例如,某银行的反洗钱计算在 11 节点的 Vertica 集群上跑了 1.5 小时,而用 SPL 重写后,单机只需 26 秒。类似地,电商漏斗运算和时空碰撞任务在使用 SPL 后,性能也大幅提升。这是因为 SQL 无法写出低复杂度的算法,而 SPL 提供了更强大的数据类型和基础运算,能够实现高效计算。
|
SQL 分布式计算 Java
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
264 0
|
SQL 分布式计算 关系型数据库
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
319 0
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
SQL 存储 监控
SQL Server的并行实施如何优化?
【7月更文挑战第23天】SQL Server的并行实施如何优化?
514 13
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
336 9