IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> hive笔记 —— 解决where子句不能使用子查询的前提下,比较子查询结果(等于,大于,平均值) -> 正文阅读

[大数据]hive笔记 —— 解决where子句不能使用子查询的前提下,比较子查询结果(等于,大于,平均值)

解决 where 字段 >(select 字段 from 表名)的情况

拿网上的题目来举例子(想把题目出处贴出来的,发现网上各种网站都有这个题目,不确定来源是哪里)

员工信息表emp:
字段:员工id,员工名字,工作岗位,部门经理,受雇日期,薪水,奖金,部门编号
英文名:EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,BONUS,DEPTNO

在这里插入图片描述

表格创建好了,数据也加载好了,现在题目需求来了

需求:列出薪金比“SMITH”多的所有员工。

我一开始写sql语句写习惯了,下意识的就写的 where sal = (select sal from emp where)这种形式的sql语句。结果发现 hive不支持在where子句中使用子查询

所以如果想在hive中,需要用到 join on 表连接的形式来完成字段值的比较
但这里如果像下面这么写的话:

select e1.* from emp as e1 
left join (select empno,sal from emp where ename='SMITH') as e2 
on e1.empno = e2.empno 
where e1.sal>e2.sal;

就会发现虽然执行成功,但是结果为空,什么都不会输出
分析一下这个sql语句,e2表里面只返回了一条语句 SMITH的empno和sal,而e1表是emp表的全部数据。此时两表进行匹配,只有SMITH的那一行能匹配成功,剩下的行都没有匹配成功,虽然因为left join的原因,左表会打印全部,但效果就跟这张图一样
在这里插入图片描述
红线右边的就是最后一列,加上去 e2.sal 的值,发现只有SMITH的那一行是有值的800,其余行因为匹配失败,都为null。这样肯定没办法完成where子句里面的 e1.sal>e2.sal;

唯一匹配成功的一行,e1.sal 是等于 e2.sal 的,因此输出结果为空

这里正确的语句是

select e1.ename,e1.sal from
(select ename,sal,1 as eid1 from emp) as e1 
left join (select 1 as eid2,sal from emp where ename='SMITH') as e2
on e1.eid1 = e2.eid2 
where e1.sal > e2.sal;

结果为
在这里插入图片描述
再来分析一下这里的语句,就会发现,之前是因为 e1表和e2表的empno的值对应不上,所以只匹配了一行。那么现在不用 empnp作为key值连接两张表了,自己手动给两张表加上一个新的列,新的列的值都为1,然后两张表分别给这一列起一个别名,eid1 和 eid2,现在来看一下,这样连接的表长什么样子
在这里插入图片描述
ok,这样就可以完成 sal值的比较了

解决 where 字段 =(select 字段 from 表名)的情况

原先在mysql中可以这样写

select * from emp as e1 where e1.sal in (select sal from emp where sal>2000) as e2;

到了hive里面就歇菜了,会报 ParseException 的错误

那么应该怎么写来替换 in 的写法呢,答案是使用 left semi join

select * from emp as e1 
left semi join emp as e2 
on (e1.empno=e2.empno and e2.sal>2000);

结果为
在这里插入图片描述
and子句可以有多个,

select * from emp as e1 
left semi join emp as e2 
on (e1.empno=e2.empno 
    and e2.sal>2000 
    and e2.ename='SMITH');

解决 where 字段 =(select avg(字段) from 表名 group by 字段)的情况

我是根据这篇博客学习后,才知道还有这种解决方法
hive sql系列(一)——找出所有科目成绩都大于某一学科平均成绩的学生

建议去源博客地址查看,我这里只是简单的写一下
在这里插入图片描述
数据如上图所示
字段含义从左到右依次为 uid学号,subject_id科目号,socre成绩

现在的需求是找出所有科目成绩都大于某一学科平均成绩的学生
因此思路应该是

  1. 求处某一学科的平均成绩
select *,cast(avg(score) over(partition by subject_id) as int) as avg 
from scoretest;

在这里插入图片描述
列的含义依次是uid,subject_id,score,每个学科的平均值

这里的开窗函数 avg(score) over(partition by subject_id) 用来求每个学科的成绩平均值,这里外面还套上了一层cast()函数,是要保证最后求出来的平均值是int类型。
如果不加上的话,结果长这个样子
在这里插入图片描述

  1. 给数据的每一行的后面都加上学科平均值之后,下一步就应该是拿每个学生的成绩与学科的平均值进行比较
select t1.*,if(t1.score > t1.avg,0,1) as flag 
from (select *,avg(score) over(partition by subject_id) as avg from scoretest) as t1;

从第一步得出的表中提取 t1.* 全部列,然后还要再加上一个新的列,列名为flag

这个列的作用是通过hive 的 if 函数来判断

if 函数 :语法: if(boolean testCondition, T valueTrue, T valueFalseOrNull)
当条件 testCondition 为 TRUE 时,返回 valueTrue;否则返回 valueFalseOrNull

因此当t1.score > t1.avg,也就是学生的成绩大于学科平均成绩时,返回的结果为0

  1. 按照 flag 来找到最后的结果,即学生的全部成绩都大于学科平均成绩的学生
select t2.uid from (select t1.*,if(t1.score > t1.avg,0,1) as flag 
from (select *,avg(score) over(partition by subject_id) as avg from scoretest) as t1) as t2
group by t2.uid
having sum(t2.flag)=0;

最后的 sum(t2.flag)=0; 如果某个学生的每一科成绩都大于学科平均成绩,那么,按照 t2.uid分组后,一个uid对应一个学生,一个组里面有一个学生的三个flag比较结果,如果sum求和后结果为0,说明flag的值都为0,也就是每一科的成绩都大于学科平均成绩。

最后的结果为
在这里插入图片描述

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-11-27 09:57:56  更:2021-11-27 09:58:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:58:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码