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

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

2.13 即时订单比例

2.13.1 题目需求

订单配送中,如果期望配送日期和下单日期相同,称为即时订单,如果期望配送日期和下单日期不同,称为计划订单。

请从配送信息表(delivery_info)中求出每个用户的首单(用户的第一个订单)中即时订单的比例,保留两位小数,以小数形式显示。期望结果如下:

percentage

0.6

2.13.2 代码实现

hive>

select
    round(sum(if(order_date=custom_date,1,0))/count(*),2) percentage
from
(
    select
        delivery_id,
        user_id,
        order_date,
        custom_date,
        row_number() over (partition by user_id order by order_date) rn
    from delivery_info
)t1
where rn=1;


骚戴理解:还是那句话,摆脱mysql的惯有思维!也就是使用传统的group by来实现的都优先考虑窗口函数,round(sum(if(order_date=custom_date,1,0))/count(*),2)我一开始想的就是用where来实现,但是round(sum(if(order_date=custom_date,1,0))/count(*),2)这样写要容易很多,简洁很多!


需要用到的表:delivery_info表

*2.14 向用户推荐朋友收藏的商品

2.14.1 题目需求

现需要请向所有用户推荐其朋友收藏但是用户自己未收藏的商品,请从好友关系表(friendship_info)和收藏表(favor_info)中查询出应向哪位用户推荐哪些商品。期望结果如下:

1)部分结果展示

user_id(用户id)

sku_id(应向该用户推荐的商品id)

101

2

101

4

101

7

101

9

101

8

101

11

101

1


2)完整结果

user_id sku_id


101 2


101 4


101 7


101 9


101 8


101 11


101 1


102 3


102 5


102 10


103 2


103 1


103 9


104 1


104 4


104 10


104 5


104 2


105 1


105 2


105 6


105 12


105 3


106 11


106 10


106 8


106 9


106 3


107 11


107 7


107 4


107 9


107 12


107 1


107 8


107 6


107 2


108 2


108 6


108 12


108 1


108 7


108 4


108 5


109 6


109 10


109 7


109 1


109 12


109 3


109 11


1010 4


1010 10


1010 6


1010 12


1010 11


1010 8


1010 3


1010 5


1010 7


2.14.2 代码实现

hive>

select
    distinct t1.user_id,
    friend_favor.sku_id
from
(
    select
        user1_id user_id,
        user2_id friend_id
    from friendship_info
    union
    select
        user2_id,
        user1_id
    from friendship_info
)t1
left join favor_info friend_favor
on t1.friend_id=friend_favor.user_id
left join favor_info user_favor
on t1.user_id=user_favor.user_id
and friend_favor.sku_id=user_favor.sku_id
where user_favor.sku_id is null;

2.15 查询所有用户的连续登录两天及以上的日期区间

2.15.1 题目需求

从登录明细表(user_login_detail)中查询出,所有用户的连续登录两天及以上的日期区间,以登录时间(login_ts)为准。期望结果如下:

user_id(用户id)

start_date(开始日期)

end_date(结束日期)

101

2021-09-27

2021-09-30

102

2021-10-01

2021-10-02

106

2021-10-04

2021-10-05

107

2021-10-05

2021-10-06


2.15.2 代码实现

hive>

select user_id,
       min(login_date) start_date,
       max(login_date) end_date
from (
         select user_id,
                login_date,
                date_sub(login_date, rn) flag
         from (
                  select user_id,
                         login_date,
                         row_number() over (partition by user_id order by login_date) rn
                  from (
                           select user_id,
                                  date_format(login_ts, 'yyyy-MM-dd') login_date
                           from user_login_detail
                           group by user_id, date_format(login_ts, 'yyyy-MM-dd')
                       ) t1
              ) t2
     ) t3
group by user_id, flag
having count(*) >= 2;
骚戴解法
SELECT 
    user_id ,
    min(date_format(login_ts,'yyyy-MM-dd')) start_date,
    max(date_format(login_ts,'yyyy-MM-dd')) end_date
FROM (
SELECT 
    user_id ,
    login_ts ,
    row_number() over(PARTITION by user_id order by login_ts) rn,
    date_sub(login_ts,row_number() over(PARTITION by user_id order by login_ts)) flag
FROM user_login_detail
)t 
GROUP BY user_id ,flag
HAVING count(flag) >1

骚戴理解:这个题目在消化了第二题后,就可以做出来了,突然就不难了哈哈,以下是需要用到的表


2.16 男性和女性每日的购物总金额统计

2.16.1 题目需求

从订单信息表(order_info)和用户信息表(user_info)中,分别统计每天男性和女性用户的订单总金额,如果当天男性或者女性没有购物,则统计结果为0。期望结果如下:

1686568339835.png

2.16.2 代码实现

hive>

select create_date,
       sum(if(gender = '男', total_amount, 0)) total_amount_male,
       sum(if(gender = '女', total_amount, 0)) total_amount_female
from order_info oi
         left join
     user_info ui
     on oi.user_id = ui.user_id
group by create_date;

骚戴理解:这题目不难,我没有摆脱惯性思维,没想到用sum(if(gender = '男', total_amount, 0)),理一下思路,首先左连接--->根据下单日期分组--->通过if函数判断是男是女--->sum来统计总数


所需要的两个表:order_info表和user_info表


*2.17 订单金额趋势分析

2.17.1 题目需求

查询截止每天的最近3天内的订单金额总和以及订单金额日平均值,保留两位小数,四舍五入。期望结果如下:

1686568386408.png


2.17.2 代码实现

hive>

select create_date,
       round(sum(total_amount_by_day) over (order by create_date rows between 2 preceding and current row ),2) total_3d,
       round(avg(total_amount_by_day) over (order by create_date rows between 2 preceding and current row ), 2) avg_3d
from (
         select create_date,
                sum(total_amount) total_amount_by_day
         from order_info
         group by create_date
     ) t1;

骚戴理解:这里我理解的近三天是连续的三天,上面的hql是有问题的,它只能统计所有数据都是连续的情况,例如第一条是2020-10-08,他就不是连续的,那么统计的2021-09-27的总数就应该是29000,但它把2020-10-08的数据也加进来了,这是有问题的,平均值也有问题,所以2021-09-27和2021-09-28的总数和平均值都是错的,但是这样的通过行来求近三天内的思路可以学习一下,order by create_date rows between 2 preceding and current row表示按create_date排序,并且获取排序后的前两行到当前行的数据,通过这个来实现“最近3天内”


2.18 购买过商品1和商品2但是没有购买商品3的顾客

2.18.1 题目需求

从订单明细表(order_detail)中查询出所有购买过商品1和商品2,但是没有购买过商品3的用户,期望结果如下:

user_id

103

105


2.18.2 代码实现

hive>

select user_id
from (
         select user_id,
                collect_set(sku_id) skus
         from order_detail od
                  left join
              order_info oi
              on od.order_id = oi.order_id
         group by user_id
     ) t1
where array_contains(skus, '1')
  and array_contains(skus, '2')
  and !array_contains(skus, '3');

骚戴理解:理清思路,把两个表left join并且按用户id分组--->每个用户下单的商品id收集成一个集合--->通过array_contains来判断是否包含对应的商品id


这里两个亮点:collect_set函数的作用是收集并形成set集合,结果去重,这里用sku_id会有重复的,所以要去重,array_contains来判断集合里有没有这个元素,有就返回true


需要用到的表:order_detail表和order_info表


2.19 统计每日商品1和商品2销量的差值

2.19.1 题目需求

从订单明细表(order_detail)中统计每天商品1和商品2销量(件数)的差值(商品1销量-商品2销量),期望结果如下:

1686568456588.png

2.19.2 代码实现

hive>

select create_date,
       sum(if(sku_id = '1', sku_num, 0)) - sum(if(sku_id = '2', sku_num, 0)) diff
from order_detail
where sku_id in ('1', '2')
group by create_date;

骚戴理解:这个题目我一开始是这样写的,但是会报错!

所需要的表:order_detail表

2.20 查询出每个用户的最近三笔订单

2.20.1 题目需求

从订单信息表(order_info)中查询出每个用户的最近三笔订单,期望结果如下:

1686568490399.png

1686568502971.png

1686568519554.png

2.20.2 代码实现

hive>

select user_id,
       order_id,
       create_date
from (
         select user_id
              , order_id
              , create_date
              , row_number() over (partition by user_id order by create_date desc) rk
         from order_info
     ) t1
where rk <= 3;

骚戴理解:“最近三笔订单”是通过排名后求最大的日期的前三天,也就是通过row_number() over (partition by user_id order by create_date desc) rk 和where rk <= 3;来实现


需要用到的表:order_info表



2.21 查询每个用户登录日期的最大空档期

2.21.1 题目需求

从登录明细表(user_login_detail)中查询每个用户两个登录日期(以login_ts为准)之间的最大的空档期。统计最大空档期时,用户最后一次登录至今的空档也要考虑在内,假设今天为2021-10-10。期望结果如下:

1686568559211.png

2.21.2 代码实现

hive>

select
    user_id,
    max(diff) max_diff
from
(
    select
        user_id,
        datediff(next_login_date,login_date) diff
    from
    (
        select
            user_id,
            login_date,
            lead(login_date,1,'2021-10-10') over(partition by user_id order by login_date) next_login_date
        from
        (
            select
                user_id,
                date_format(login_ts,'yyyy-MM-dd') login_date
            from user_login_detail
            group by user_id,date_format(login_ts,'yyyy-MM-dd')
        )t1
    )t2
)t3
group by user_id;

骚戴理解:这个题目有点难度,先理清思路,首先对日期进行格式化并且以用户id和格式化后的日期进行分组--->通过lead() over()函数来查询下一个登录日期--->通过datediff函数求差值--->通过max取最大值


group by user_id,date_format(login_ts,'yyyy-MM-dd')这里分组是因为要去重,因为同一天内同一个用户可能登录多次


lead(login_date,1,'2021-10-10') over(partition by user_id order by login_date) 是核心,用来实现求下一次的日期,这个语句要从后往前看,先看over(partition by user_id order by login_date) 这个无非就是分组加排序,并不陌生,值得一提的是这个partition by有时候可以不写!然后再看lead(login_date,1,'2021-10-10')的意思是求login_date的下一次的日期,如果没有下一次就用2021-10-10来作为下一次日期,例如下面红色画出来的部分

  1. 这个题目我一开始是这样写的


我一开始想用date_sub函数来求两个日期只差,但是报错

可以看出这个date_sub函数不能用于string类型的日期,当然它这个日期设置为string也不合理,至于这各报错为什么显示的是date_add函数我也不知道,然后我使用datediff函数就可以了


我一开始没有写最后的这个group by user_id,然后报错如下


这里报语法错误是因为select后面用到了max函数,所以必须分组!而且从语义来讲也要分组,因为会有重复的,如下所示,可以看到101有三条重复的1,所以需要分组!

  1. 需要用到的表:user_login_detail表


相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps&nbsp;
目录
相关文章
|
3月前
|
存储 机器学习/深度学习 分布式计算
大数据技术——解锁数据的力量,引领未来趋势
【10月更文挑战第5天】大数据技术——解锁数据的力量,引领未来趋势
|
2月前
|
存储 机器学习/深度学习 SQL
大数据处理与分析技术
大数据处理与分析技术
163 2
|
3月前
|
存储 分布式计算 数据可视化
大数据常用技术与工具
【10月更文挑战第16天】
206 4
|
2月前
|
存储 分布式计算 NoSQL
【赵渝强老师】大数据技术的理论基础
本文介绍了大数据平台的核心思想,包括Google的三篇重要论文:Google文件系统(GFS)、MapReduce分布式计算模型和BigTable大表。这些论文奠定了大数据生态圈的技术基础,进而发展出了Hadoop、Spark和Flink等生态系统。文章详细解释了GFS的架构、MapReduce的计算过程以及BigTable的思想和HBase的实现。
127 0
|
3月前
|
存储 数据采集 监控
大数据技术:开启智能决策与创新服务的新纪元
【10月更文挑战第5天】大数据技术:开启智能决策与创新服务的新纪元
|
22天前
|
分布式计算 大数据 数据处理
技术评测:MaxCompute MaxFrame——阿里云自研分布式计算框架的Python编程接口
随着大数据和人工智能技术的发展,数据处理的需求日益增长。阿里云推出的MaxCompute MaxFrame(简称“MaxFrame”)是一个专为Python开发者设计的分布式计算框架,它不仅支持Python编程接口,还能直接利用MaxCompute的云原生大数据计算资源和服务。本文将通过一系列最佳实践测评,探讨MaxFrame在分布式Pandas处理以及大语言模型数据处理场景中的表现,并分析其在实际工作中的应用潜力。
58 2
|
1月前
|
SQL 运维 大数据
轻量级的大数据处理技术
现代大数据应用架构中,数据中心作为核心,连接数据源与应用,承担着数据处理与服务的重要角色。然而,随着数据量的激增,数据中心面临运维复杂、体系封闭及应用间耦合性高等挑战。为缓解这些问题,一种轻量级的解决方案——esProc SPL应运而生。esProc SPL通过集成性、开放性、高性能、数据路由和敏捷性等特性,有效解决了现有架构的不足,实现了灵活高效的数据处理,特别适用于应用端的前置计算,降低了整体成本和复杂度。
|
2月前
|
SQL 算法 大数据
为什么大数据平台会回归SQL
在大数据领域,尽管非结构化数据占据了大数据平台80%以上的存储空间,结构化数据分析依然是核心任务。SQL因其广泛的应用基础和易于上手的特点成为大数据处理的主要语言,各大厂商纷纷支持SQL以提高市场竞争力。然而,SQL在处理复杂计算时表现出的性能和开发效率低下问题日益凸显,如难以充分利用现代硬件能力、复杂SQL优化困难等。为了解决这些问题,出现了像SPL这样的开源计算引擎,它通过提供更高效的开发体验和计算性能,以及对多种数据源的支持,为大数据处理带来了新的解决方案。
|
2月前
|
机器学习/深度学习 存储 大数据
在大数据时代,高维数据处理成为难题,主成分分析(PCA)作为一种有效的数据降维技术,通过线性变换将数据投影到新的坐标系
在大数据时代,高维数据处理成为难题,主成分分析(PCA)作为一种有效的数据降维技术,通过线性变换将数据投影到新的坐标系,保留最大方差信息,实现数据压缩、去噪及可视化。本文详解PCA原理、步骤及其Python实现,探讨其在图像压缩、特征提取等领域的应用,并指出使用时的注意事项,旨在帮助读者掌握这一强大工具。
107 4
|
2月前
|
机器学习/深度学习 存储 大数据
云计算与大数据技术的融合应用
云计算与大数据技术的融合应用