HiveSQL面试

2024-03-04 20:38
文章标签 面试 hivesql

本文主要是介绍HiveSQL面试,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

手写HQL 第1题

表结构:uid,subject_id,score

求:找出所有科目成绩大于某一学科平均成绩学生

思路:求出所有科目的平均成绩,若都大于平均成绩则为0,否则为1;

求和都是0则都大于平均成绩

 

数据集如下

1001   01  90

1001   02  90

1001   03  90

1002   01  85

1002   02  85

1002   03  70

1003   01  70

1003   02  70

1003   03  85

1)建表语句

create table score(

    uid string,

    subject_id string,

    score int)

row format delimited fields terminated by '\t';

2)求出每个学科平均成绩

select

    uid,

    score,

    avg(score) over(partition by subject_id) avg_score   ---按学号分组求出平均值

from

    score;t1 

3)根据是否大于平均成绩记录flag,大于则记为0,否则记为1

select

    uid,

    if(score>avg_score,0,1) flag

from

    t1;t2

4)根据学生id进行分组统计flag的和,和为0则是所有学科都大于平均成绩

select

    uid

from

    t2

group by

    uid

having                     ---在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与聚合函数一起使用。

                                ---HAVING 子句可以让我们筛选分组后的各组数据

    sum(flag)=0;

5)最终SQL

select

    uid

from

    (select

        uid,

        if(score>avg_score,0,1) flag

from

    (select

        uid,

        score,

        avg(score) over(partition by subject_id) avg_score

from

    score) t1 ) t2

group by

    uid              --分组

having

    sum(flag)=0;      ---筛选

 1)核心问题剖析

从最终的需求可以看出,我们计算的结果是随着行的变化变化,我们把这类问题称为移动计算。在hivesql中其实解决此类问题我们是通过移动窗口来解决的,类似于spark中的滑动窗口。那么控制此类行的变化范围hive中给出了具体的方法--窗口子句。

窗口:over()分析函数如:row_number(),max(),lag()等。

分析函数+窗口函数:窗口的本质就是指明了分析函数分析数据时要处理的数据范围(作用域)。

窗口分为静态窗口和移动窗口(也叫滑动窗口),静态窗口指分析数据的范围是固定不变的滑动窗口按照行的变化,窗口数据也随着变换,不同的行对应着不同的窗口数据(类似于与spark中的滑动窗口,随着时间的变化,窗口数据也发生着变化)。窗口也是SQL编程的思维本质,就是对范围内的数据进行处理。

窗口子句:窗口函数包括三个窗口子句。分组:partition by; 排序:order by; 窗口大小:rows.使用语法如下:

over(partition by xxx order by yyy rows between zzz)

 

窗口子句范围大小的控制:

rows或(range)子句往往来控制窗口边界范围的,其语法如下:

ROWS between CURRENT ROW | UNBOUNDED PRECEDING | [num] PRECEDING AND  UNBOUNDED FOLLOWING | [num] FOLLOWING| CURRENT ROW
 

 
RANGE between [num] PRECEDING  AND [num]FOLLOWING

      CURRENT ROW:当前行;
      n PRECEDING:往前n行数据;
      n FOLLOWING:往后n行数据;
      UNBOUNDED:起点,UNBOUNDED PRECEDING 表示从前面的起点, UNBOUNDED FOLLOWING表示到后面的终点;
 

注意:

rows:rows是真实的行数,也就是我们实际中所说的1,2,3...连续的行数。

range:range是逻辑上的行数,所谓的逻辑行指的就是需要通过计算才能知道是哪一行。range后面跟计算表达式,对order by后面的某个字段值进行计算,计算后的结果表示其真正的范围。(逻辑偏移量构成)。

id 列
1
1
3
6
6
6
7
8
9
分析下面两个语句:
SUM(ID) over(ORDER BY ID ROWS BETWEEN 1 preceding AND 2 following) rows_sum
SUM(ID) over(ORDER BY ID RANGE BETWEEN 1 preceding AND 2 following) range_sum

1.物理上的rows:表示从当前行为参考点,数据范围为前一行与后两行范围内求得的结果。数据范围为:

当前行为第一行时:数据范围如下图所示

sum(id)=1+1+3=5

当前行为第二行时:数据范围如下图所示

 sun(id)=1+1+3+6=11

当前行为第三行时:数据范围如下图所示

sum(id) = 1+3 +6 +6=16

......

整个过程如下图所示

整个窗口的变化过程就像按照每一行进行移动,移动的数据范围由窗口子句指定

2.逻辑上的range:数据的范围需要按照id进行计算。

计算公式为:RANGE BETWEEN 1 preceding AND 2 following。

翻译为:当前行的值(此处为id的值,具体是以order by 后字段进行计算的)id-1=<id<=id +2。简单的说就是到当前行为止,id的值在[id-1,id-2]范围内的所有行的统计值。

当为第一行时:id=1,计算公式为id-1=<id<=id +2 范围为:0~3的id值,注意此处不是0到3行,而是id值为0到3的所有行。具体如下图所示:

sum(id)=1+1+3=5

当为第四行时:id=6, 计算公式为id-1=<id<=id +2,范围为:[5,8]。即id值包含在5~8之间的所有行,id值大于5小于8的行。具体如下图所示

sum(id) = 6+6+6+7+8=33

range的应用场景:比如有一张员工薪资表。我想知道比当前员工薪资高1000元的员工总数。此时range就很好用。

窗口函数几点认识如下:

a 当窗口函数over()出现分组(partition by)子句时:

unbounded preceding即第一行是指表中一个分组里的第一行, unbounded following即最后一行是指表中一个分组里的最后一行;

b 当开窗函数over()无分组(partition by)子句时

unbounded preceding即第一行是指表中的第一行, unbounded following即最后一行是指表中的最后一行。

c 而无论是否省略分组子句,以下结论都是成立的:

1、窗口子句不能单独出现,必须有order by子句时才能出现。
 
2、当省略窗口子句时:
 
a) 如果存在order by则默认的窗口是unbounded preceding and current row  --当前组的第一行到当前
 
行,即在当前组中,第一行到当前行
 
b) 如果没有order by则默认的窗口是unbounded preceding and unbounded following  --整个组
 

总结如下:

                 有分组有order by 则为分组中第一行到当前行
                 有分组无order by 则为整个分组
                 无分组有order by 则为整个表中第一行到当前行
                 无分组无order by 则为整个表。即over()       

d.窗口函数中的分组与group by的区别1

1.group by 分组返回值只有一个一组中只返回一个结果。窗口函数中partition by分组每组每行中都会有一个分析结果。
   select 中的字段必须出现在group by中,而窗口函数中partition by分组则无此限制,其分析的结果可以与表中的其他字段并列,其相当于在原表每个分组中添加了一列
2.如果开窗函数在 group by后的结果集中使用时,那么窗口中无其他限定时,一般把一组看成一条记录,相当于先进行分组后,分组后这一组内整体的记录数被作为一条记录。窗口函数也是基于整个group by后的查询结果,而不是基于每组组内的查询结果。
3.group by 汇总后行数减少,partition by汇总后原表中的行数没变。这个也是为什么使用窗口函数分组而不使用group by的原因。具体如下所示:

e 窗口函数执行顺序及使用规则

(1)先看sql的执行顺序
  1 from
 
  2 on
 
  3 join
 
  4 where
 
  5 group by
 
  6 with
 
  7 having
  
  8 select
 
  9 distinct
 
  10 order by
 
  11 limit
 
(2) 窗口函数执行顺序:窗口函数只能在select命令中和select命令之后使用,不能在where中使用,其执行顺序是和select同级别的,位于distinct顺序之前,可以把窗口函数与分析函数结合后形成的看成select中字段一样,也是可以取别名的,是select的一部分。和聚合函数不能在where语句中使用是一个道理。

f.窗口函数与group by的区别2

通过e,HiveSQL的执行顺序我们知道,窗口函数的执行是在group by,having之后进行,是与select同级别的,所以我们可以得出窗口函数的partition by与group by的一个重要区别就是,如果SQL中既使用了group by又使用了partition by,那么此时partition by的分组基于group by分组之后的再次分组,分析的数据范围也是基于group by后的数据。一定要注意分析函数如count(*)只是针对over()中的数据进行分析。例如:先进行了group by XXX 后使用了count(*) over(partition by XXX),此时count只是对group by 后的数据再进行partition by后进行统计。

窗口中的partition by不进行去重而group by进行去重

例子:

name    orderdate    cost
jack    2017-01-01    10
jack    2017-02-03    23
jack    2017-01-05    46
jack    2017-04-06    42
jack    2017-01-08    55
mart    2017-04-08    62
mart    2017-04-09    68
mart    2017-04-11    75
mart    2017-04-13    94

(1)实验1:用group by及partiton by进行分组。

    =======================gruop by=======================
    select
        name,
        count(*)
    from
        overdemo
    where
        date_format(orderdate,'yyyy-MM')='2017-04'
    group by
        name;
    --------结果---------
    name    _c1
    jack    1
    mart    4
    =======================partition by========================
    select
        name,
        count(*) over(partition by name)
    from
        overdemo
    where
        date_format(orderdate,'yyyy-MM')='2017-04';
    --------结果---------
    name    count_window_0
    jack    1
    mart    4
    mart    4
    mart    4
    mart    4

  • 实验结果:group by去重,partition by不去重

 

 (2)实验2:在group by基础上再进行partiton by

=====先group by name后over(partition by name)=====
select
    name,
    count(*) over(partition by name)
from
    overdemo
where
    date_format(orderdate,'yyyy-MM')='2017-04'
group by 
    name;
---------结果--------
name    count_window_0
jack    1
mart    1
 
对比实验
=======================只有gruop by的情况=======================
    select
        name,
        count(*)
    from
        overdemo
    where
        date_format(orderdate,'yyyy-MM')='2017-04'
    group by
        name;
    --------结果---------
    name    _c1
    jack    1
    mart    4
===

这篇关于HiveSQL面试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/774369

相关文章

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

java面试常见问题之Hibernate总结

1  Hibernate的检索方式 Ø  导航对象图检索(根据已经加载的对象,导航到其他对象。) Ø  OID检索(按照对象的OID来检索对象。) Ø  HQL检索(使用面向对象的HQL查询语言。) Ø  QBC检索(使用QBC(Qurey By Criteria)API来检索对象。 QBC/QBE离线/在线) Ø  本地SQL检索(使用本地数据库的SQL查询语句。) 包括Hibern

贝壳面试:什么是回表?什么是索引下推?

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很重要的面试题: 1.谈谈你对MySQL 索引下推 的认识? 2.在MySQL中,索引下推 是如何实现的?请简述其工作原理。 3、说说什么是 回表,什么是 索引下推 ? 最近有小伙伴在面试 贝壳、soul,又遇到了相关的

毕业前第二次面试的感慨

距面试已经过去了有几天了,我现在想起来都有说多的恨感慨。 我一直都是想找刚刚起步的企业,因为这能让我学到更多的东西,然而正好有一家企业是刚起步的,而且他还有自己的产品专利,可以说这是一家,即是创业又是刚起步的公司,这家公司回复了我投给他的简历,这家企业想进一步了解我的情况,因为简历上我符合这家企业的基本要求,所以要进一步了解。 虽然面试的过程中,他给我的面试题,我做得并不是很理想,

腾讯社招面试经历

前提:本人2011年毕业于一个普通本科,工作不到2年。   15号晚上7点多,正在炒菜做饭,腾讯忽然打电话来问我对他们的Linux C++的职位是否感兴趣,我表达了我感兴趣之后,就开始了一段简短的电话面试,电话面试主要内容:C++和TCP socket通信的一些基础知识。之后就问我一道算法题:10亿个整数,随机生成,可重复,求最大的前1万个。当时我一下子就蒙了,没反应过来,何况我还正在烧

完整的腾讯面试经过

从9月10号开始到现在快两个月了,两个多月中,我经历数次面试和笔试,在经历这些的同时积累了不少的经验,也学到了不少东西,在此把它记录下来,算是和一起找工作中的同学一起共勉吧。我是本校的学生,专业是机械制造及其自动化,找工作的主要目标是计算机软件类和机械制造方向的国内的企业,所以意向去外企的同学就不必浪费时间看这些面经啦,想去国内IT企业的同学可以继续看下去。本贴中我把最近的腾讯面试经过写下

仕考网:结构化面试流程介绍

(一)结构化面试 结构化面试,也叫做标准化面试,考官按照预先设定好的一套试题以问答方式与应试者当面交谈,根据应试者的言语、行为表现,对其相关能力和个性特征作出相应评价。 (二)考试流程 抵达考场——审核抽签——面试候考——进入考场——面试答题——考生退场——计分审核 (三)答题技巧 1.声音洪亮,音量可以比平时说话声音大一点。 2.语速不要过快,语速快容易卡顿,而且不便于考官听清答

嵌入式面试经典30问:二

1. 嵌入式系统中,如何选择合适的微控制器或微处理器? 在嵌入式系统中选择合适的微控制器(MCU)或微处理器(MPU)时,需要考虑多个因素以确保所选组件能够满足项目的具体需求。以下是一些关键步骤和考虑因素: 1.1 确定项目需求 性能要求:根据项目的复杂度、处理速度和数据吞吐量等要求,确定所需的处理器性能。功耗:评估系统的功耗需求,选择低功耗的MCU或MPU以延长电池寿命或减少能源消耗。成本

Leetcode面试经典150题-128.最长连续序列-递归版本另解

之前写过一篇这个题的,但是可能代码比较复杂,这回来个简洁版的,这个是递归版本 可以看看之前的版本,两个版本面试用哪个都保过 解法都在代码里,不懂就留言或者私信 class Solution {/**对于之前的解法,我现在提供一共更优的解,但是这种可能会比较难懂一些(思想方面)代码其实是很简洁的,总体思想如下:不需要排序直接把所有数放入map,map的key是当前数字,value是当前数开始的