首页 > 其他分享 >Hive的一些基本函数(二)

Hive的一些基本函数(二)

时间:2024-09-07 14:23:06浏览次数:3  
标签:基本 01 函数 04 over Hive orderdate 2018 order

一、窗口函数

当查询的要求,既要明细查询又要统计查询的时候,这时候考虑开窗,通过over语法让两种查询同时执行

比如:需求:查询每个订单的信息,以及订单的总数


姓名,购买日期,购买数量
saml,2018-01-01,10
saml,2018-01-08,55
tony,2018-01-07,50
saml,2018-01-05,46
tony,2018-01-04,29
tony,2018-01-02,15
saml,2018-02-03,23
mart,2018-04-13,94
saml,2018-04-06,42
mart,2018-04-11,75
mart,2018-04-09,68
mart,2018-04-08,62
neil,2018-05-10,12
neil,2018-06-12,80


-1. 创建order表:
create table if not exists t_order
(
    name      string,
    orderdate string,
    cost      int
)  row format delimited fields terminated by ',';
-2. 加载数据:
load data local inpath "/xxxx/xxx/xxxx.txt" into table t_order;


--不使用开窗函数的写法
select *,(select count(1) from t_order) as `订单总数` from t_order ;

--使用开窗函数的写法:
select *, count(*) over() from t_order;





窗口函数是针对每一行数据的.
如果over中没有指定参数,默认窗口大小为全部结果集

需求:查询在2018年1月份购买过的顾客购买明细及总次数

select *,count(*) over()
from t_order
where substr(orderdate,1,7) = '2018-01';

需求:查询在2018年1月份购买过的顾客购买明细及总人数。

select *,count(distinct name) over()
from t_order
where substr(orderdate,1,7) = '2018-01';

distribute by子句:

在over窗口中进行分组,对某一字段进行分组统计,窗口大小就是同一个组的所有记录(按照所给字段分组)

案例:查看顾客的购买明细及月购买总额

select *,sum(cost) over(distribute by substr(orderdate,1,7) ) from t_order ;

sort by子句

用在分组后表,会强制排序,当使用排序时,窗口会在组内逐行变大

案例:查看顾客的购买明细及每个顾客的月购买总额,并且按照日期降序排序

select *,sum(cost) over(distribute by name,month(orderdate) sort by orderdate desc ) from t_order ;

我们可以使用partiton by + order by 组合替代 distribute by +sort组合

select *,sum(cost) over(partition by name,month(orderdate) order by orderdate desc ) from t_order ;

也可以在窗口函数中,只写排序,窗口大小是全表记

select *,sum(cost) over(order by orderdate desc ) from t_order ;

window 子句

如果要对窗口的结果做更细粒度的划分,那么就使用window子句,常见的有下面几个
PRECEDING:往前 
FOLLOWING:往后 
CURRENT ROW:当前行 
UNBOUNDED:起点,
UNBOUNDED PRECEDING:表示从前面的起点, 
UNBOUNDED FOLLOWING:表示到后面的终点

select name,orderdate,cost,
       sum(cost) over() as sample1, -- 所有行相加
       sum(cost) over(partition by name) as sample2,-- 按name分组,组内数据相加
       sum(cost) over(partition by name order by orderdate) as sample3,-- 按name分组,组内数据累加
       sum(cost) over(partition by name order by orderdate rows between UNBOUNDED PRECEDING and current row )  as sample4 ,-- 与sample3一样,由起点到当前行的聚合
       sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING   and current row) as sample5, -- 当前行和前面一行做聚合
       sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING   AND 1 FOLLOWING  ) as sample6,-- 当前行和前边一行及后面一行
       sum(cost) over(partition by name order by orderdate rows between current row and UNBOUNDED FOLLOWING ) as sample7 -- 当前行及后面所有行
from t_order;

注意:默认mysql老版本没有支持,在最新的8.0版本中支持, Oracle和Hive中都支持窗口函数

二、序列函数

1、NTILE

        ntile 是Hive很强大的一个分析函数。可以看成是:它把有序的数据集合 平均分配 到 指定的数量(num)个桶中, 将桶号分配给每一行。如果不能平均分配,则优先分配较小编号的桶,并且各个桶中能放的行数最多相差1

select name,orderdate,cost,
ntile(3) over(partition by name) -- 按照name进行分组,在分组内将数据切成3份
from t_order;

-- 运行结果如下:
mart    2018-04-13      94      1
mart    2018-04-08      62      1
mart    2018-04-09      68      2
mart    2018-04-11      75      3
neil    2018-06-12      80      1
neil    2018-05-10      12      2
saml    2018-02-03      23      1
saml    2018-04-06      42      1
saml    2018-01-05      46      2
saml    2018-01-08      55      2
saml    2018-01-01      10      3
tony    2018-01-02      15      1
tony    2018-01-04      29      2
tony    2018-01-07      50      3




        需求:获取一个表中,所有消费记录中,每一个人,最后50%的消费记录

select name,orderdate,cost from (
select name,orderdate,cost,
ntile(2) over(partition by name order by orderdate ) as xuhao
from t_order ) t where t.xuhao=2;

2、lag 和lead函数

lag返回当前数据前n行数据

lead返回当前数据后n行数据

需求:查询顾客上次购买的时间

select * ,lag(orderdate,1) over( partition by name order by orderdate ) from t_order;

mart    2018-04-08      62      NULL
mart    2018-04-09      68      2018-04-08
mart    2018-04-11      75      2018-04-09
mart    2018-04-13      94      2018-04-11
neil    2018-05-10      12      NULL
neil    2018-06-12      80      2018-05-10
saml    2018-01-01      10      NULL
saml    2018-01-05      46      2018-01-01
saml    2018-01-08      55      2018-01-05
saml    2018-02-03      23      2018-01-08
saml    2018-04-06      42      2018-02-03
tony    2018-01-02      15      NULL
tony    2018-01-04      29      2018-01-02
tony    2018-01-07      50      2018-01-04

select * ,lag(orderdate,1,'1990-01-01') over( partition by name order by orderdate ) from t_order;

mart    2018-04-08      62      1990-01-01
mart    2018-04-09      68      2018-04-08
mart    2018-04-11      75      2018-04-09
mart    2018-04-13      94      2018-04-11
neil    2018-05-10      12      1990-01-01
neil    2018-06-12      80      2018-05-10
saml    2018-01-01      10      1990-01-01
saml    2018-01-05      46      2018-01-01
saml    2018-01-08      55      2018-01-05
saml    2018-02-03      23      2018-01-08
saml    2018-04-06      42      2018-02-03
tony    2018-01-02      15      1990-01-01
tony    2018-01-04      29      2018-01-02
tony    2018-01-07      50      2018-01-04

3、first_value 和last_value

first_value 取分组内排序后,截止到当前行,第一个值

last_value 分组内排序后,截止到当前行,最后一个值

select name,orderdate,cost,
   first_value(orderdate) over(partition by name order by orderdate) as time1,
   last_value(orderdate) over(partition by name order by orderdate) as time2
from t_order;

name    orderdate       cost    time1   time2
mart    2018-04-08      62      2018-04-08      2018-04-08
mart    2018-04-09      68      2018-04-08      2018-04-09
mart    2018-04-11      75      2018-04-08      2018-04-11
mart    2018-04-13      94      2018-04-08      2018-04-13
neil    2018-05-10      12      2018-05-10      2018-05-10
neil    2018-06-12      80      2018-05-10      2018-06-12
saml    2018-01-01      10      2018-01-01      2018-01-01
saml    2018-01-05      46      2018-01-01      2018-01-05
saml    2018-01-08      55      2018-01-01      2018-01-08
saml    2018-02-03      23      2018-01-01      2018-02-03
saml    2018-04-06      42      2018-01-01      2018-04-06
tony    2018-01-02      15      2018-01-02      2018-01-02
tony    2018-01-04      29      2018-01-02      2018-01-04
tony    2018-01-07      50      2018-01-02      2018-01-07

三、排名函数

      1、row_number

                row_number从1开始,按照顺序,生成分组内记录的序列,row_number()的值不会存在重复,当排序的值相同时,按照表中记录的顺序进行排列

效果如下:
98		1
97		2
97		3
96		4
95		5
95		6

没有并列名次情况,顺序递增

        2、rank()

生成数据项在分组中的排名,排名相等会在名次中留下空位

效果如下:
98		1
97		2
97		2
96		4
95		5
95		5
94		7
有并列名次情况,顺序跳跃递增

        3、dense_rank()

        生成数据项在分组中的排名,排名相等会在名次中不会留下空位

       

效果如下:
98		1
97		2
97		2
96		3
95		4
95		4
94		5
有并列名次情况,顺序递增

案例演示:

1 gp1808 80
2 gp1808 92
3 gp1808 84
4 gp1808 86
5 gp1808 88
6 gp1808 70
7 gp1808 98
8 gp1808 84
9 gp1808 86
10 gp1807 90
11 gp1807 92
12 gp1807 84
13 gp1807 86
14 gp1807 88
15 gp1807 80
16 gp1807 92
17 gp1807 84
18 gp1807 86
19 gp1805 80
20 gp1805 92
21 gp1805 94
22 gp1805 86
23 gp1805 88
24 gp1805 80
25 gp1805 92
26 gp1805 94
27 gp1805 86


create table if not exists stu_score(
userid int,
classno string,
score int
)
row format delimited 
fields terminated by ' ';

load data local inpath '/xxx/xxxxx/xxxxxx.txt' overwrite into table stu_score;

需求一:对每个班级的每次考试按照考试成绩倒序

select *,dense_rank() over(partition by classno order by  score desc) from stu_score;

select *,dense_rank() over(order by score desc) `全年级排名`  from stu_score;

需求二:获取每次考试的排名情况

select *,
-- 没有并列,相同名次依顺序排
row_number() over(distribute by classno sort by score desc) rn1,
-- rank():有并列,相同名次空位
rank() over(distribute by classno sort by score desc) rn2,
-- dense_rank():有并列,相同名次不空位
dense_rank() over(distribute by classno sort by score desc) rn3
from stu_score;

需求三:求每个班级的前三名

select * from (
select * ,dense_rank() over(partition by classno order by score desc) as paiming from stu_score) t  where  paiming <=3;

标签:基本,01,函数,04,over,Hive,orderdate,2018,order
From: https://blog.csdn.net/KasarJ/article/details/141995086

相关文章

  • opencv-python学习笔记2-opencv基本操作
    目录 一、opencv架构:(1)OpenCV的主要模块包括:(2)OpenCV的架构特点:(3)OpenCV的应用场景:二、图像输入输出模块imgcodecs: a.imread:b. imwrite:三、opencv界面编程:(1)创建窗口:(2)显示图像:(3)添加滑块:(4)处理鼠标事件:(5)等待用户输入(6)销毁窗口四、单窗口显示多图片:(1)np.hstack()......
  • Go-函数的那些事儿
    Go-函数的那些事儿定义函数是结构化编程的最小模块单元。它将复杂的算法过程分解为若干较小任务,隐藏相关细节,使得程序结构更加清晰,易于维护。函数被设计成相对独立,通过接收输入参数完成一段算法指令,输出或存储相关结果。因此,函数还是代码复用和测试的基本单元。Go函数借......
  • 结合回调函数处理异步任务结果
    结合回调函数处理异步任务结果的过程可以比作在等待一份重要的快递时安排一个通知服务。这个通知服务就是回调函数,它会在快递送达时通知你,或者在处理完成后执行特定的操作。在Java的CompletableFuture中,这种模式可以通过supplyAsync()、thenApply()、thenAccept()和handle(......
  • SQL 自定义函数 生成网卡地址,MES开发中经常会用到的
    SQL自定义函数生成网卡地址,MES开发中经常会用到的ALTERFunction[dbo].[Fun_ReleaseMACadd]( @CurrentSeqNovarchar(6))Returnsvarchar(18)-------------------------------------------------------------------------------------------------As--------------......
  • 数据结构基本概念和术语
    1.1.数据:是描述客观事物的符号,是计算机中可以操作的对象,是能被计算机识别,并输入给计算机处理的符号集合。数据不仅仅包括整型,实型等数值类型,还包括字符及声音,图像,视频等非数值类型。1.2.数据元素:是组成数据的,有一定意义的基本单位,在计算机中通常作为一个整体处理。也被称为......
  • HTTP协议基本知识点:工作原理、http请求、响应、连接以及缓存机制
    目录一、HTTP概述二、HTTP的版本三、HTTP请求1.请求方法2.请求头四、HTTP响应1.状态码2.响应头五、HTTP持久连接六、缓存机制1.CacheControl2.ETag3.LastModified七、安全性八、使用场景总结 一、HTTP概述 全称:超文本传输协议(HyperTextTransferProtoco......
  • redis的基本使用
    Redis简介Redis是完全开源免费的,遵守BSD协议,高性能的基于键值对(key-value)的NoSQL(NotOnlySQL)数据库。SQL(StructQueryLanauge结构化的查询语言)。引申含义RDBMS产品,传统的关系型数据库,存储格式化的表格数据。NOSQL(NotOnlySQL)不仅仅只有关系型数据库。引申含......
  • 字符串查找函数strchr 、 strrchr和strstr的简介
    目录一、函数简介1.1. strchr 函数1.2.strrchr函数1.3. strstr 函数二、函数原型2.1. strchr 函数参数返回值2.1. strchr 函数参数返回值2.2. strstr 函数参数返回值三、函数实现(伪代码)3.1.strchr实现3.2.strrchr实现3.3. strstr实现四、......
  • Canvas艺术之旅:了解几个绘制基本图形的 API
    了解几个绘制基本图形的APICanvas是HTML5提供的绘画API,可以用于在Web页面上绘制各种基本图形。本文介绍一些Canvas绘制基本图形的API:前置条件注意:本文章所提供的代码示例默认已经进行了canvas元素定义,DOM获取以及canvas的上下文获取,以下进行代码演示时将......
  • (14)DDS基本原理与FPGA实现
    基本概念DDS(DirectDigitalSynthesizer),即数字合成器,是一种把一系列数字信号通过D/A转换器转化成模拟信号的数字合成技术DDS的实现有两种方式:查表法和计算法,下面将主要介绍DDS查表法的FPGA实现查表法:预先在ROM中存放不同相位对应的幅度序列,通过相位累加器的输出对其进行寻址,经......