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()  爆炸函数 (炸裂函数)
 */
  1. 简单来说:SQL函数中的UDF、UDAF和UDTF就像是“数据处理的三剑客”,分别擅长“单点突破”、“团队协作”和“多点开花”,满足不同的数据处理需求。

  2. 具体而言:

    • UDF(用户自定义函数):
      • 比喻:像是“单兵作战”,一对一处理数据。
      • 特点:输入一个值,输出一个值。
      • 示例:split()(字符串分割)、substr()(字符串截取)。
      • 实现:在Hive中继承UDF类,实现evaluate方法。
    • UDAF(用户自定义聚合函数):
      • 比喻:像是“团队协作”,多对一聚合数据。
      • 特点:输入多行数据,输出一个聚合结果。
      • 示例:sum()(求和)、avg()(平均值)、count()(计数)。
      • 实现:在Hive中继承UDAF类,实现init()、iterate()、merge()等方法。
    • UDTF(用户自定义表生成函数):
      • 比喻:像是“多点开花”,一对多展开数据。
      • 特点:输入一行数据,输出多行数据。
      • 示例:explode()(将数组或Map展开为多行)。
      • 实现:在Hive中继承GenericUDTF类,实现initialize()、process()等方法。
  3. 实际生产场景:

    • 在数据清洗中,使用UDF对字符串进行格式化处理。
    • 在数据分析中,使用UDAF计算复杂的业务指标,如加权平均值。
    • 在数据展开中,使用UDTF将嵌套的JSON数据拆分为多行,便于后续分析。
  4. 总之: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;

更多推荐