Day08_hive表操作&函数
·
文章目录
Day08_随堂笔记
1:今日内容
1:HQL -DQL语句 联合查询
2:HQL- DQL语句 虚拟列(了解)
3:HQL- DQL语句 CTE表达式
4:Hive函数详解
4-1:函数的分类 (UDF、UDAF、UDTF)
4-2:字符串相关函数
4-3:数字相关的函数
4-4:日期相关函数
4-5:加密相关函数
4-6:转换相关函数
4-7:其他函数
5:Hive调优
1:HQL -DQL语句 联合查询❤
---------------HQL语句 -DQL -union 联合查询--------
/**
1:union 联合查询介绍
概述: 对表的数据做纵向拼接,类似于电子书上下页感觉
2:分类
union distinct:合并字段,并且去重,distinct可以省略
union all :合并,不去重
3:细节
1:union all 和union区别
2:要进行union联合查询的时候,要求列的个数,对应的数据类型要一致
3:如果条件写到上面 ,查询语句后,则:单独作用域该SQL
如果条件写到下面,查询语句后,则:作用全局
4:面试题 full join 和 union all 区别?
1:作用不同
full join :横向合并
union all :纵向合并
2:条件要求不同
full join :对表的列数和类型无要求
union all :要求列的个数,对应的数据类型要一致
*/
create database day08;
use day08;
CREATE table student_p(
id int ,
name string,
sex string,
age int,
major string
)ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
CREATE table student_u(
id int ,
name string,
sex string,
age int,
major string
)ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
SELECT * from student_p;
-- 演示 :union all -- 单表44 特点:合并不去重
SELECT * from student_p
union ALL
SELECT * from student_u;
-- 演示: union distinct 22条 特点:合并去重
SELECT * from student_p
union DISTINCT
SELECT * from student_u;
--
-- 如果条件写到上面 ,查询语句后,则:单独作用域该SQL
(SELECT * from student_u LIMIT 3)
union ALL
SELECT *
FROM student_p ;
-- 如果条件写到下面,查询语句后,则:作用全局
SELECT * FROM student_u
union all
SELECT * from student_p LIMIT 3; -- 3 25
2:HQL- DQL语句 虚拟列(了解)
---------------------------HQL语句 -DQL -虚拟列--------
/**
1:什么是虚拟列?
Hive内置的查询语句,使用他可以看到表数据本身的详细参数
2:Hive目前可以使用三个虚拟列
INPUT__FILE__NAME,显示数据行所在的具体文件
BLOCK__OFFSET__INSIDE__FILE,显示数据行所在文件的偏移量
ROW__OFFSET__INSIDE__BLOCK,显示数据所在HDFS块的偏移量
此虚拟列需要设置:SET hive.exec.rowoffset=true 才可使用
3: 细节
1:中文在utf-8码表中占用3个字节 ,在gbk码表中占用2个字节
2:数字、字母、特殊符号,无论在什么码表下,都只占用一个字节
3:HDFS文件和Linux文件类型,默认的换行符都是\n
*/
-- 1:显示数据行所在的具体文件
SELECT INPUT__FILE__NAME from student_u;
--2:显示数据行所在文件的偏移量
SELECT BLOCK__OFFSET__INSIDE__FILE from student_u;
--3: 显示数据所在HDFS块的偏移量
--!! 执行前需要设置临时参数
SET hive.exec.rowoffset=true
SELECT ROW__OFFSET__INSIDE__BLOCK from student_u;
3:HQL- DQL语句 CTE表达式❤
---------------HQL语句 -DQL -CTE表达式--------
/**
1:CTE介绍
概述:公共表达式 ,就是用于临时存储某些数据结果
格式:
with cte表达式名字 as (
select 语句 , 即:要被临时存储的内容
)
....
select * from cte表达式名字
2:写法
1:标准写法 ❤
2:from风格写法
3:链式编程 ❤
4:结合union all 或者 join
5:用数据表永久的存储结果 ❤
6:用视图临时存储结果
*/
--1:标准写法
WITH t1 as(
SELECT * from student_u
)
SELECT * from t1;
-- 2:from风格写法
WITH t1 as (
SELECT *from student_u
)from t1 SELECT id,name;
-- 3:链式编程
WITH t1 as (SELECT *from student_u),
t2 as (select *from t1 LIMIT 10),
t3 as (SELECT id ,name from t2)
SELECT * from t3;
-- 4:结合union all 或者 join
WITH t1 as (SELECT *from student_u),
t2 as (select *from t1 LIMIT 10)
SELECT * from t1
UNION all
SELECT * from t2;
-- 4.2 join
WITH t1 as (SELECT *from student_u),
t2 as (select *from t1 LIMIT 10)
SELECT *from t1 FULL JOIN t2 on t1.id=t2.id;
-- 5:用数据表永久的存储结果 练习
show tables;
CREATE table bf1 as
with t1 as (
SELECT * from student_u
)
SELECT id,name,age from t1;
SELECT * from bf1;
desc FORMATTED bf1;
-- 6:用视图临时存储结果
CREATE VIEW bf2 as
with t1 as (
SELECT * from student_u
)
SELECT id,name,age from t1;
SELECT * from bf2;
4:Hive函数详解
-------------------------Hive 函数详解----------------------------
/**
Hive函数的划分介绍:
最初Hive分为内置函数和用户自定义两大类,用户自定义分为三类
分类:
UDF: 全称 user defined function,用户自定义函数 也要普通函数
特点:一进一出
例如:abs,rand
UDAF:全称 user defined aggregate function,用户自定义聚合函数
特点:多进一出
例如: sum \count\avg\max\min
UDTF:全称 user defined table Generating function,用户自定义表函数 也叫作:表生成函数
特点: 一进多出
例如:explode() 爆炸函数 (炸裂函数)
*/
-
简单来说:SQL函数中的UDF、UDAF和UDTF就像是“数据处理的三剑客”,分别擅长“单点突破”、“团队协作”和“多点开花”,满足不同的数据处理需求。
-
具体而言:
- UDF(用户自定义函数):
- 比喻:像是“单兵作战”,一对一处理数据。
- 特点:输入一个值,输出一个值。
- 示例:
split()(字符串分割)、substr()(字符串截取)。 - 实现:在Hive中继承
UDF类,实现evaluate方法。
- UDAF(用户自定义聚合函数):
- 比喻:像是“团队协作”,多对一聚合数据。
- 特点:输入多行数据,输出一个聚合结果。
- 示例:
sum()(求和)、avg()(平均值)、count()(计数)。 - 实现:在Hive中继承
UDAF类,实现init()、iterate()、merge()等方法。
- UDTF(用户自定义表生成函数):
- 比喻:像是“多点开花”,一对多展开数据。
- 特点:输入一行数据,输出多行数据。
- 示例:
explode()(将数组或Map展开为多行)。 - 实现:在Hive中继承
GenericUDTF类,实现initialize()、process()等方法。
- UDF(用户自定义函数):
-
实际生产场景:
- 在数据清洗中,使用UDF对字符串进行格式化处理。
- 在数据分析中,使用UDAF计算复杂的业务指标,如加权平均值。
- 在数据展开中,使用UDTF将嵌套的JSON数据拆分为多行,便于后续分析。
-
总之:UDF、UDAF和UDTF是SQL中强大的扩展工具,分别适用于“一对一”、“多对一”和“一对多”的数据处理场景,为业务需求提供了灵活的支持。
4-1:字符串函数
-------------------1:字符串相关函数------------------------------------、
-- split() -- 分割字符串 格式:split(参数1,参数2) 参数1:要切割的字符串 参数2:切割符(支持正则) 【掌握】
SELECT split("a1b2c3d",'1') ; --["a","b2c3d"]
SELECT split("a1b2c3d",'[0-9]') ; --["a","b","c","d"]
-- concat() 默认拼接符是'',可以进行任意类型拼接
SELECT concat('-','aa','bb',11,'false'); -- -aabb11false
-- concat_ws() 可以指定拼接符 ,参1:拼接符号 参2..... 要拼接内容 --掌握
SELECT concat_ws('-','aa','bb','11','false'); -- !!!只能拼接字符串,或者字符数组 aa-bb-11-false
-- trim() 移除两端空格
SELECT trim(" it a c ");
-- substr() 参1:要操作字符串 参数2 :从几开始截取,默认是1 参数3:截取多少位
SELECT substr("hello bigdata hadoop hive",2,3);
SELECT substr("hello bigdata hadoop hive",-4);
-- substring() --掌握
-- 1,7 年月
-- 1,10 年月日
SELECT substring('2024-11-08 10:46:22',1,10);
-- lower() 大写转小写
SELECT lower("HELLO BIGDATA");-- hello bigdata
-- upper()
SELECT upper("hello bigdata");
-- regexp_replace() -- 正则替换 参1:要操作的字符串 参2:正则表达式 参数3:替换后的内容 掌握
SELECT regexp_replace("www.baidu.baidu.com","baidu","google");
-- parse_url() 从url地址中解析出内容 ,参1:url 地址 参2:要解析内容
SELECT parse_url("https://itheima.com/index.html?username=root&password=123456",'HOST');
SELECT parse_url("https://itheima.com/index.html?username=root&password=123456",'PATH');
SELECT parse_url("https://itheima.com/index.html?username=root&password=123456",'QUERY');
SELECT parse_url("https://itheima.com/index.html?username=root&password=123456",'QUERY','username');
-- HOST: 提取主机名。
-- PATH: 提取路径。
-- QUERY: 提取查询字符串。
-- REF: 提取片段标识符(#后面的部分)。
-- PROTOCOL: 提取协议(如 http, https)。
-- AUTHORITY: 提取权威部分(包括用户名、密码和主机名)。
-- FILE: 提取文件部分(包括路径和片段标识符)。
SELECT parse_url("https://itheima.com/index.html?username=root&password=123456",'AUTHORITY');
-- get_json_object() -- 【!!!掌握】
/**
1:get_json_object 处理json字符串 参数1:json字符串 参数2:从json中解析对应的内容 可以使用$代表整个json字符串或者json数组
2:json字符串介绍
概述:它是一个特殊规则的字符串,由键值对组成,需要双引号包裹
格式:{"key":"value","key":"value"}
作用: 一般前后端传输数据的,跨域传输 把数据从前端传输到后端代码
细节:json字符串也有数组形式[{"key":"value"},{"key":"value"}....]
*/
SELECT get_json_object('{"name":"黄晓明","wife":"杨颖"}','$.wife');
SELECT get_json_object('{"name":"黄晓明","wife":"叶柯"}','$.name');
SELECT get_json_object('[{"name":"黄晓明","wife":"叶柯"},{"name":"黄晓明","wife":"杨颖"}]','$.[1].wife');
4-2:时间函数
---------------------------------------2:时间相关函数------------------------------------
-- 1打印当前时间戳
SELECT `current_timestamp`() ;
-- 2打印当前时间
SELECT `current_date`();
-- 获取当前秒值
SELECT unix_timestamp();
-- 秒值转换为时间 0时区 东八区
SELECT from_unixtime(1731036453);
-- current_timestamp 指定 年月日
SELECT to_date(`current_timestamp`());
-- 计算你活了多少天
SELECT (unix_timestamp()- unix_timestamp('2000-01-01 00:00:00'))/3600/24;
-- 计算两个日期差 !!!!重要❤
SELECT datediff('2000-01-05 00:00:00','2000-01-10 00:00:00');
-- 从日期中获取对应的内容
SELECT year('2000-01-05 00:00:00');
SELECT month('2000-01-05 00:00:00');
SELECT day('2000-01-05 00:00:00');
SELECT hour('2000-01-05 00:00:00');
SELECT minute('2000-01-05 00:00:00');
SELECT second('2000-01-05 00:00:00');
SELECT quarter('2000-01-05 00:00:00'); -- 【掌握】
-- 指定偏移时间
SELECT date_add('2000-01-05 00:00:00',2);
SELECT date_add('2000-01-05 00:00:00',-2);
4-3:数字相关函数
SELECT abs(-10); -- 绝对值
SELECT round(10.344,2); -- 四舍五入
SELECT rand();
-- 获取一个1~100直接随机数
SELECT int((rand()*100)+1);
--天花板数
SELECT ceil(10.3);
SELECT ceil(10.0);
--地板数
SELECT `floor`(10.3);
--pow(a,b) 计平方值 a的b次幂
SELECT pow(3,2);
4-4:hive条件转换函数
-- if() 函数 判断, 条件成立返回值1 条件不成立返回值2 参数1:条件表达式 参数2:值1 参数3:值2
SELECT if(5>3,'成立','不成立');
-- SELECT if(5>3,if(2>3,'成立','不成立'),'不成立');
--2:isnull 判断是否为null
SELECT isnull('null'); --false
SELECT isnull(''); --false
SELECT isnull(null); -- true
--3:isnotnull 判断是否不为null
--4 nvl() 空值转换 ,判断参数1是否为空, 不为空就返回其值,为空就返回参数2
SELECT nvl(null,"itheima");
-- 检查数据质量
SELECT count(nvl(null,1));
--5.case when
-- 写法一:
select
case
when 5>3 then '大于'
when 5<3 then '小于'
else '等于'
end as num1;
-- 写法二:
SELECT
case 1
when 1 then '星期一'
when 2 then '星期二'
else '没有这个时间'
end as week;
-- 6:cast函数 类型转换
SELECT cast(10.9 as int );
SELECT cast(10 as string );
SELECT cast ('123' as int );
4-5:脱敏和加密
-- 哈希值
SELECT hash('admin');
-- 加密相关函数
-- 第一次:注册 123456 密码:e10adc3949ba59abbe56e057f20f883e
-- 第二次:123456 md5(123456) e10adc3949ba59abbe56e057f20f883e
SELECT md5(md5("aaaaavadfdsafadfa"));
SELECT md5('123456');
SELECT sha1('aaaaavadfdsafadfa');
SELECT sha2('aaaaavadfdsafadfa',256);
SELECT crc32('adfad');
-- 脱敏
SELECT mask('xyzABC123'); -- 默认顺序:大写字母X 小写字母是x数字n
-- SELECT mask('xyzABC123','X','小');
-- 只脱敏前几个
SELECT mask_first_n('xyzABC123',4);
SELECT mask_show_first_n('xyzABC123',4); -- 除了前四个其他都处理
-- 需求:对手机号进行脱敏
-- 为什么要对数据进行脱敏 1:保护用户信息 2:人员流动大(外包)
-- 手机号脱敏规则 : 17600648944 中间四位:176****8944
-- 第一步:切割:substr(手机号,1,3)+'****'+substr(手机号,8,4)
SELECT
-- substr('17600648944',1,3),
-- substr('17600648944',-4),
-- mask(substr('17600648944',4,4),'X','x','*'),
concat(substr('17600648944',1,3) , mask(substr('17600648944',4,4),'X','x','*'),substr('17600648944',-4) ),
concat(substr('17600648944',1,3) , "****",substr('17600648944',-4) )
4-6:炸裂函数&侧视图❤
------------------------------Hive 炸裂函数---------------------
/**
1: explode() 函数一般在列转行,爆炸函数, 即:一进多出
*/
-- 案例:
-- 1:查询一个数组 ,数组里面有3个元素
SELECT `array`(11,22,33);
--2:炸
SELECT explode(`array`(11,22,33)); -- 一进多出 进去的是一个数组。
SELECT explode(map(11,22,33)); --- 报错:map类型是键值对,必须成对出现
--1: 建表: NBA 夺冠球队信息
CREATE table The_NBA_Championship(
team_name string COMMENT '队名',
championship_year array<string> COMMENT '夺冠年份'
)ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' -- 切割后:“Chicago Bulls” ,"1991|1992|1993|1996|1997|1998"
COLLECTION ITEMS TERMINATED BY '|'; --切割后:“Chicago Bulls”,["1991","1992"...]
-- 2:上传数据:9870 讲义&软件包&测试数据\02_测试数据\测试数据\cs The_NBA_Championship.txt
-- 2:上传hdfs路径 :/user/hive/warehouse/day08.db/the_nba_championship
--3:查询表
SELECT * from The_NBA_Championship;
-- 3-1: 源数据格式
-- Chicago Bulls ["1991","1992","1993","1996","1997","1998"]
-- 转换为:
--Chicago Bulls 1991
--Chicago Bulls 1992
--Chicago Bulls 1993
--Chicago Bulls 1996
-- .....
--4:思路很简单 把 championship_year 用explode炸裂出来即可
SELECT explode(championship_year) as championship_year from The_NBA_Championship;
--5:走到这里,就剩最后一步,在这个基础上加上队名
SELECT team_name,explode(championship_year) as championship_year from The_NBA_Championship; -- 想法ok ,但是报错
--6:思考:为什么报错?
-- 产生原因:炸裂后的数据,无法直接和原表查询,因为对应的关联信息不精准(炸裂后的每一行,具体对应的炸裂前的哪一行数据,对不上) --
--解决方案:通过侧视图实现,它是Hive提供一个一种专门用来记录炸裂前后,数据的对应关系
--侧视图格式: lateral view 炸裂函数 侧视图名字 as 炸裂后数据的列名
-- 7:实现代码
SELECT a.team_name,b.championship_year from The_NBA_Championship a
LATERAL VIEW explode(championship_year) b as championship_year;
4-7:collect_list函数❤
----------------------Hive---行转列------------------
/**
行转列涉及到的函数
采集函数
collect_list() 采集,不去重,有序(元素存放顺序和取出顺序一致,不是指排序)
collect_set() 采集 ,去重 ,无序
拼接函数
concat 默认拼接符''
concat_ws 可以指定拼接符
*/
-- 1:建表
CREATE table row2col2(
col1 string,
col2 string ,
col3 int
)ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
-- 2:上传文件 讲义&软件包&测试数据\02_测试数据\测试数据\cs\行列转换\r2c2.txt
-- 2:上传到 /user/hive/warehouse/day08.db/row2col2/r2c2.txt
--3: 验证数据
SELECT * from row2col2;
--4 : 行传列
-- 第一步 :
-- col1 col2
-- a b
-- c d
SELECT col1,col2 from row2col2
GROUP BY col1,col2;
-- 第二步:使用collect_list收集函数
SELECT col1,col2,collect_list(col3)
from row2col2
GROUP BY col1,col2;
--第三步:col3 拼接 - concat_ws('-',col3)
SELECT col1,col2,concat_ws('-',collect_list(col3))
from row2col2
GROUP BY col1,col2;
-- 报表:类型不匹配,要string给的int SemanticException [Error 10016]: Line 1:33 Argument type mismatch 'col3': Argument 2 of function CONCAT_WS must be "string or array<string>", but "array<int>" was found.
-- 第四步:cast(要转换的列 as 转换的类型)
SELECT col1,col2,concat_ws('-',collect_list(cast(col3 as string)))
from row2col2
GROUP BY col1,col2;
4-8:爆炸函数案例❤
--1:建表
CREATE table col2row2(
col1 string,
col2 string,
col3 string
)ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
-- 2:上传数据:c2r2.txt
--3:校验:
SELECT * from col2row2;
-- 4: 实现
--4-1 提示:需要对col3进行提前切割
SELECT explode(col3) from col2row2;
SELECT explode(split('1,2,3',',')) ;
SELECT a.col1,a.col2,b.col3 from col2row2 as a
lateral view explode(split(col3,',')) b as col3;
4-9:JSON格式解析
---------------------------------Hive---处理json文件----------------------
/**
Hive中处理JSON字符串主要思路有两种
思路一:以普通的字符串形式存储json 然后再逐个解析 先存,在解析
1:get_json_object :逐个解析
2:json_tuple 批量解析
思路二:在加载(建表)遇到json文件的时候直接解析 存的时候直接解析
*/
-- 思路一:以普通的字符串形式存储json 然后再逐个解析 先存,在解析
-- 1:get_json_object :逐个解析
-- 2:json_tuple 批量解析
-- 1:建表
CREATE table t_json2(
json string
);
-- 2:上传文件 :device.json
SELECT * from t_json2;
--3-1:get_json_object :逐个解析
SELECT
get_json_object(json ,'$.device') as device, -- 设备名
get_json_object(json,'$.deviceType') as deviceType, -- 设备类型
get_json_object(json ,'$.signal') as signal, -- 信号强度
get_json_object(json,'$.time') as `time` -- 数据采集时间
from t_json2;
--3-2:json_tuple
SELECT
json_tuple(json,'device','deviceType','signal','time') as (device,deviceType,signal,`time`)
from t_json2;
-- 思路二:在加载(建表)遇到json文件的时候直接解析 存的时候直接解析
--1:建表
CREATE table t_json3(
device string ,
deviceType string,
signal string,
`time` string
)
-- 默认的类型lazySimpleSerDe类实现不了我们的需求 ,需要使用hive专门处理json数据Serder类,即:jsonserde类
row format SerDe 'org.apache.hive.hcatalog.data.JsonSerDe';
SELECT * FROM t_json3;
4-10:开窗函数
1:开窗函数入门
------------------------Hive开窗函数--------------------------------
/**
窗口函数
概述:
窗口函数相当于给表增加一个新的列,至于新增列是什么内容,取决于窗口函数结合什么函数一起使用
窗口函数指的是over()函数, 可以限制窗口的范围,进行局部、全局的
格式(全):
over(partition by 分组字段 order by 排序字段 asc|desc rows between 起始行 and 结束行)
窗口函数可以和哪些函数一起使用? 分为3类
1:聚合函数
count() ,sum () ,max() ,min(),avg()
2:排序函数
row_number(),rank(),dense_rank(),ntile(n)
3:其他函数
lag(),lead(),first_value(),last_value()
细节:
1:窗口函数相当于给表新增一个列 ,至于新增列是什么内容,取决于窗口函数结合什么函数一起使用
2:如果不写partition by ,默认是全局统计 ,如果写了,则只组内数据统计(局部统计)
3:如果不写order by ,默认是统计组内所有的数据,如果写了,则统计组内第一行至当前行的数据
4:通过rows between 来限定操作数据的范围
unbounded preceding: 起始行
n preceding 向上n行
current row 当前行
n following 向下n行
unbounded following 最后1行
5:ntile(n)是几分之几 ,表示把数据分成几份,优先参考最小分区
例如:7条数据 分3份 3 2 2
6:常用的窗口函数:count() ,sum () ,max() ,min(),avg(),row_number(),rank(),dense_rank(),lag()
*/
2:窗口函数**+**聚合函数
SELECT * from website_pv_info;
-- 需求:求出网站总的pv数,所有的用户加起来。
-- 如果over()里面什么都不写,默认操作:该列全部数据
SELECT *, sum(pv) over() from website_pv_info;
--需求:求出每个用户的pv总数
-- 聚合函数+窗口函数
SELECT * ,sum(pv) over(partition by cookieid) as total_pv from website_pv_info;
-- 排序: order by 时间进行排序
-- 组内第一行,到当前行
SELECT * ,sum(pv) over(partition by cookieid order by createtime) as total_pv from website_pv_info;
-- 写法二:
SELECT * ,sum(pv) over(partition by cookieid order by createtime rows BETWEEN UNBOUNDED PRECEDING and CURRENT ROW) as total_pv from website_pv_info;
-- 需求 : 统计每个cookieid 的pv(访问量) 只统计: 当前行及 向前3行 向后1行
SELECT * ,sum(pv) over(partition by cookieid order by createtime rows BETWEEN 3 PRECEDING and 1 FOLLOWING ) as total_pv from website_pv_info;
SELECT * from website_pv_info;
--
-- 5:ntile(n)是几分之几 ,表示把数据分成几份,优先参考最小分区
-- 例如:7条数据 分3份 3 2 2
SELECT
* ,
ntile(3) over(PARTITION BY cookieid ORDER BY pv desc) as nt from website_pv_info;
3:开窗函数之其他函数
-- lag: 统计窗口内往上第n行的值
SELECT * from website_url_info;
-- lag(createtime) 获取上1个createtime列值
SELECT * ,lag(createtime) over(partition by cookieid order by createtime) from website_url_info;
-- first_value
-- 取分组内排序后,截止当前行的,第一个值
SELECT * ,first_value(createtime) over(partition by cookieid order by createtime) from website_url_info;
-- 取分组内排序后,截止当前行的,最后一个值
SELECT * ,last_value(createtime) over(partition by cookieid order by createtime) from website_url_info;
4:开窗函数之排序❤
排序函数指的是: row_number(), rank(), dense_rank(), 它们都可以做排名, 不同的是, 对相同值的处理结果.
例如: 数据是100, 90, 90, 60,
row_number是: 1, 2, 3, 4, rank: 1, 2, 2, 4, dense_rank: 1, 2, 2, 3
需求:
select
*,
row_number() over (partition by cookieid order by pv desc ) as rn, -- 根据用户id分组, 根据点击量, 降序排列.
rank() over (partition by cookieid order by pv desc ) as rk,
dense_rank() over (partition by cookieid order by pv desc ) as dr
from website_pv_info;
更多推荐


所有评论(0)