Hive SQL

一、基本数据类型

tinyint 1byte 有符号整数

smallint 2byte 有符号整数

int 4byte 有符号整数

bigint 8byte 有符号整数

boolean 布尔类型,true或者false

float 单精度浮点数

double 双精度浮点数

decimal 十进制精准数字类型 decimal(16,2)

varchar 字符序列,需指定最大长度,最大长度的范围是[1,65535] varchar(32)

string 字符串,无需指定最大长度

timestamp 时间类型

binary 二进制数据

array 数组是一组相同类型的值的集合 array arr[0]

map map是一组相同类型的键-值对集合 map<string, int> map['key']

struct 结构体由多个属性组成,每个属性都有自己的属性名和数据类型 struct<id:int, name:string> struct.id

二、基本查询

Home - Apache Hive - Apache Software Foundation

1、语法:

sql 复制代码
SELECT [ALL | DISTINCT] select_expr, select_expr, ...
FROM table_reference -- 从什么表查
[WHERE where_condition] -- 过滤
[GROUP BY col_list] -- 分组查询
[HAVING col_list] -- 分组后过滤
[ORDER BY col_list] -- 排序 -- 全局排序
[CLUSTER BY col_list   -- 分区排序(当 distribute by 和 sort by 字段相同时,可以使用 cluster by方式。)
| [DISTRIBUTE BY col_list] [SORT BY col_list]
]
[LIMIT number] -- 限制输出的行数

2、join连接

左右关联:inner、outer均可省略

内连接(join或inner join):只有2个表中连接字段都匹配的数据才会被保留。

左外连接(left join或left outer join):保留左表记录,右边不符合条件的用null填充

右外连接(right join或right outer join)

满外连接(full join或full outer join):保留两边全部,任一表没有符合条件的用null填充

左半连接(left semi join):内连接后,仅返回左表剩余的数据

交叉连接(笛卡尔积cross join):所有表中的所有行互相连接。

3、union和union all上下拼接:

union和union all在上下拼接sql结果时有两个要求:

(1)两个sql的结果,列的个数必须相同

(2)两个sql的结果,上下所对应列的类型必须一致

union去重并对结果排序,union all不去重

4、排序

(1)全局排序(Order By)

全局排序,只有一个Reduce。asc(ascend):升序(默认)desc(descend):降序

通常和limit一起使用,可以让每个map只需要处理limit的个数数据

(2)每个Reduce内部排序(Sort By)

Sort by为每个reduce产生一个排序文件。每个Reduce内部进行排序,对全局结果集来说不是排序。

(3)分区(Distribute By)

distribute by类似MapReduce中partition(自定义分区),进行分区,结合sort by使用。

分区排序(Cluster By)

(4)当distribute by和sort by字段相同时,可以使用cluster by方式。cluster by除了具有distribute by的功能外还兼具sort by的功能。但是排序只能是升序排序。

三、常用函数

1、单行函数

输入一行,输出一行

  1. round:四舍五入

  2. ceil:向上取整

  3. floor:向下取整

  4. if(condition, trueValue, falseValue)

  5. case when:case when a then b [when c then d]* [else e] end :条件判断函数;如果a为true,则返回b;如果c为true,则返回d;否则返回 e ;针对同一个字段的等值判断可以把字段提在case后面

  6. cast(stuId AS INT) :类型转换

  7. nvl(A,B) :替换null值 ;A的值不为null,则返回A,否则返回B

  8. substring:截取字符串substring(string A, int start, int len)

  9. replace :替换 ;replace(string A, string B, string C) 字符串A中的子字符串B替换为C。

  10. regexp_replace:正则替换 ;regexp_replace(string A, string B, string C) 将字符串A中的符合java正则表达式B的部分替换为C。

  11. regexp:正则匹配;select 'dfsaaaa' regexp 'dfsa+',正则匹配成功,输出true

  12. repeat:重复字符串;repeat(string A, int n),字符串A重复n遍

  13. split(string str, string pat) :将一个字符串根据指定的分隔符进行分割,并返回一个数组。eg:split(arr,','),split(arr,'\\')[0]。当逗号作为分隔符时,保持不变,其他多数时候要加转义,如split(properties,'\_')

  14. concat(string A, string B, string C, ......) 将A,B,C......等字符拼接为一个字符串

  15. concat_ws(分隔符, string...| array(string)): 指定分隔符拼接字符串或者字符串数

  16. get_json_object(string json_string, string path) 解析json的字符串json_string,返回path指定的内容。如果输入的json字符串无效,那么返回NULL。select get_json_object('[{"name":"大海海","sex":"男","age":"25"},{"name":"小宋宋","sex":"男","age":"47"}]','$.[0].name');

  17. unix_timestamp:返回当前或指定时间的时间戳;例如:

    select unix_timestamp('2022/08/08 08-08-08','yyyy/MM/dd HH-mm-ss');

    from_unixtime(bigint unixtime[, string format]) 转化UNIX时间戳到当前时区的时间格式

  18. select current_date:-- 获取当前日期,格式:2022-09-13

  19. date_format(date,格式) -- 如:date_format('2022-09-13 12:00:00', 'yyyy-MM-dd')

  20. current_timestamp:-- 获取当前时间戳。 2022-09-13 17:52:57.613

  21. fom_unixtime(bigint unixtime[, string format]); -- 把UNIX 时间戳(从1970-01-01 00:00:00 UTC 到指定时间的秒数)转为时间或者指定格式日期。

  22. unix_timestamp(time) -- 把yyyy-MM-dd HH:mm:ss转为unix时间戳

  23. to_date(time) -- 转为日期格式,默认为yyyy-MM-dd格式。

  24. datediff:两个日期相差的天数(结束日期减去开始日期的天数)

  25. date_add(string startdate, int days) :日期加天数

  26. date_sub (string startdate, int days) 日期减天数

  27. year(date) -- 获取年份

  28. month(date) -- 获取月份

  29. day(date) -- 获取日

  30. hour(date) -- 获取小时

  31. minute(date) -- 获取分钟

  32. second(date) -- 获取秒

  33. last_day(date) -- 指定日期所在月份的最后一天

  34. weekofyear(date) --返回日期在该年的周数

  35. -- 判断周几

    select

    case when dayofweek('${etl_date}') =1 then '星期日'

    when dayofweek('${etl_date}') =7 then '星期六'

    when dayofweek('${etl_date}') =6 then '星期五'

    when dayofweek('${etl_date}') =5 then '星期四'

    when dayofweek('${etl_date}') =4 then '星期三'

    when dayofweek('${etl_date}') =3 then '星期二'

    when dayofweek('${etl_date}') =2 then '星期一'

    else null

    end as weekday

  36. map (key1, value1, key2, value2, ...) 根据输入的key和value对构建map类型

  37. map_keys: 返回map中的key;map_values: 返回map中的value;

    select map_keys(map('xiaohai',1,'dahai',2));

  38. array(val1, val2, ...) 根据输入的参数构建数组array类

  39. array_contains: 判断array中是否包含某个元素 ;select array_contains(array('a','b','c','d'),'a');

  40. sort_array:将array中的元素排序

  41. struct(val1, val2, val3, ...) 根据输入的参数构建结构体struct类

2、高级聚合函数

多进一出 (多行传入,一个行输出)。

  1. 普通聚合 count/sum.

  2. collect_set():多行数据收集为一行,返回set集合,无序不重复

  3. collect_list():多行数据收集为一行,返回list集合,有序重复

3、炸裂函数UDTF(制表函数)

接收一行,输出多行。

常用的UDTF ----explode(array as 字段名)

常用的UDTF ----explode(map as (key,value))

常用的UDTF ----poseexplode(array as 字段名) 会返回位置,索引

常用的UDTF ----inline(array<STRUCTf1:T1,....fn,Tn> as 字段名)

Latera View:通常与UDTF配合使用。Lateral View可以将UDTF应用到源表的每行数据,将每行数据转换为一行或多行,并将源表中每行的输出结果与该行连接起来,形成一个虚拟表。

eg:

sql 复制代码
select col1, col2, tmp_table.tmp_col
from test_tb
lateral view explode(split(col3, '分隔符')) tmp_table as tmp_col
where partition_name='xxx' 
sql 复制代码
-- create table if not exists tb
-- (
--    class    string comment '班级名称',
--    student string comment '学生名称',
--    score   string comment '学生分数'
--)
--    comment '学生成绩表';
--INSERT overwrite table tb
--VALUES ("1班","小A,小B,小C","80,92,70"),
--       ("2班","小D,小E","88,62"),
--       ("3班","小F,小G,小H","90,97,85");

select class, student, score,
    stu_name, stu_score
from tb 
 lateral view posexplode(split(student, ',')) tmp3 as stu_index1, stu_name
 lateral view posexplode(split(score, ',')) tmp4 as stu_index2, stu_score
where stu_index1 = stu_index2;

-- tmp_table:explode形成的新虚拟表,可以不写;
-- tmp_col:explode 形成的新列(字段)

4、窗口函数

窗口函数,function(arg):对应的窗口数据计算函数

function(arg) over (partition by {分区列名} order by {order 列名} desc|asc [rows|range between 起点行 and 终点行])

(1)常用窗口-窗口计算

1)sum(col) over ()

2)avg(col) over ()

3)max(col) over ()

4)min(col) over ()

5)count(col) over ()

6)cume_dist() over (order by col)

--如果按升序排列,则统计:小于等于当前值的行数/总行数(number of rows ≤ current row)/(total number ofrows)。

--如果是降序排列,则统计:大于等于当前值的行数/总行数

eg: cume_dist() over (ORDER BY salary) as cume_dist -- 统计小于等于当前工资的人数占总人数的比例

cume_dist() over (PARTITION BY dept_no ORDER BY salary) as cume_dist -- 根据部门统计小于等于当前工资的人数占部门总人数的比例

(2)常用窗口-跨行取值函数

1)first_value(col) over ():首行值

2)last_value(col) over ():末行值

lag和lead:获取当前行的上、下某行、某个字段的值;不支持自定义窗口范围。

  1. lag(col,n,defaultValue) over(partion by..order by..):查询字段col,当前行往前数第n行的数据,若为null显示默认值defaultValue;

lag(col):指默认每次取字段col当前行的上一行数据

lag(col, n) over ():取窗口范围往前第 n 行数据的值

  1. lead(col, n,defaultValue) over ():取窗口范围往后第 n 行数据的值

  2. ntile(n) over(partition by col1 order by col2):col1为分组的列名,col2为排序的列名,将有序分组的窗口范围,平均分成n份,每一份编号依次为1、2、3...、n;如果要取其中第m份,需要用到嵌套子查询

(3)常用窗口-排名函数

row_number() over (partition by col1 order by col2) as row_number

-- 连续排序。在窗口内会对所有数值,每个组输出的序号唯一且连续,如:1、2、3、4、5。

rank() over (partition by col1 order by col2) as rank

-- 相同数值,输出相同的序号,而且下一个序号间断,如:1、1、3、3、5。

dense_rank() over (partition by col1 order by col2) as rank

-- 相同数值,输出相同的序号,但下一个序号不间断,如:1、1、2、2、3。

percent_rank() over():返回order by列的百分比排名

四、导入导出文件

1、load将文件导入hive表中

语法:LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)];

(1)local:表示从本地加载数据到Hive表;否则从HDFS加载数据到Hive表。(如果是本地数据则是复制一份到hive路径,如果是HDFS则是移动到hive路径)

(2)overwrite:表示覆盖表中已有数据,否则表示追加。

(3)partition:表示上传到指定分区,若目标是分区表,需指定分区。

eg:load data local inpath '/opt/module/hive/datas/dept_20220401.log'

into table dept_partition partition(day='20220401');

2、将hive查询导出到本地文件

INSERT OVERWRITE LOCAL DIRECTORY '/path/to/local/directory'

ROW FORMAT DELIMITED

FIELDS TERMINATED BY ','

LINES TERMINATED BY '\n'

SELECT * FROM your_hive_table;

五、sql使用

1、随机抽样

sql 复制代码
-- 随机抽样
use dmr_dev;
create table if not exists feature_train_202009 as
(
    select uid, req_dt, flag, req_month, feature_libsvm
    from tb
    where req_dt='2020-09-28'
    order by rand()
    limit 10000
);

-- 随机抽样
select * 
from tb
TABLESAMPLE(10 ROWS);

-- 随机抽样(百分比)
select * 
from tb 
TABLESAMPLE(10 PERCENT);

2、hive窗口函数去重

sql 复制代码
use dmr_dev;
set hive.support.quoted.identifiers=none;  
create table if not exists dmr_dev.bussiness_pinkey_all_feature as
(
    select (num)?+.+
    from
    (
        select row_number() over (partition by req_dt, uid order by req_dt, uid asc) num, *
        from dmr_dev.all_bussiness_pinkey_all_feature
    ) t
    where t.num=1
); 

3、求分位数

sql 复制代码
-- 分位数
use dmr_dev;
drop table if exists dmr_dev.dmrc_model_anti_fraud_outer_tx_if_result_i_m_array;
create table if not exists dmr_dev.dmrc_model_anti_fraud_outer_tx_if_result_i_m_array as    
select
    percentile_approx(predict_score,array(0.25,0.5,0.75,0.9,0.95)) as predict_score_arr
from (select a.*
      from
      (
        select *
        from dmr_c.dmrc_model_anti_fraud_outer_tx_if_result_i_m
        where dt = '2021-10-01'
      ) a
      join (select count(1) as cnt
            from dmr_c.dmrc_model_anti_fraud_outer_tx_if_result_i_m
            where dt = '2021-10-01'
          ) b
      where rand(123) < 100000/cnt
    ) tmp;

-- 省略ON条件,Hive将尝试进行笛卡尔积(Cartesian product),即将第一个表的每一行与第二个表的每一行组合

4、模型打分分箱,效果分析

sql 复制代码
-- 基于3求分位数后,模型打分分箱
-- (,arr[0]]   1
-- (arr[0], arr[1]]   2
-- (arr[1], arr[2]]   3
-- (arr[2], arr[3]]   4
-- (arr[3], arr[4]]   5
-- (arr[4], )    6

CREATE TEMPORARY MACRO score_grp(x double,arr array<double>) 
    case when x<=arr[0] then 1 
    when x<=arr[1] then 2 
    when x<=arr[2] then 3 
    when x<=arr[3] then 4 
    when x<=arr[4] then 5 
    when x>arr[4] then 6 end;

use dmr_dev;
drop table if exists dmr_dev.dmrc_model_anti_fraud_outer_tx_if_result_i_m_score;
create table if not exists dmr_dev.dmrc_model_anti_fraud_outer_tx_if_result_i_m_score as
select a.*,
    score_grp(a.predict_score, b.predict_score_arr) as predict_score_grp
from 
(   select *
    from dmr_c.dmrc_model_anti_fraud_outer_tx_if_result_i_m
    where dt = '2021-10-01' 
) a
left join dmr_dev.dmrc_model_anti_fraud_outer_tx_if_result_i_m_array b;
-- 此处省略on条件


-- 模型效果分析
select predict_score_grp, count(1) as cnt
from dmr_dev.dmrc_model_anti_fraud_outer_tx_if_result_i_m_score
group by predict_score_grp
order by predict_score_grp;
相关推荐
阿里云大数据AI技术6 小时前
用 SQL 调大模型?Hologres + 百炼,让数据开发直接“对话”AI
sql·llm
tryCbest5 天前
数据库SQL学习
数据库·sql
十月南城5 天前
数据湖技术对比——Iceberg、Hudi、Delta的表格格式与维护策略
大数据·数据库·数据仓库·hive·hadoop·spark
王九思5 天前
Hive Thrift Server 介绍
数据仓库·hive·hadoop
cowboy2585 天前
mysql5.7及以下版本查询所有后代值(包括本身)
数据库·sql
努力的lpp5 天前
SQL 报错注入
数据库·sql·web安全·网络安全·sql注入
麦聪聊数据5 天前
统一 Web SQL 平台如何收编企业内部的“野生数据看板”?
数据库·sql·低代码·微服务·架构
山峰哥5 天前
吃透 SQL 优化:告别慢查询,解锁数据库高性能
服务器·数据库·sql·oracle·性能优化·编辑器
Asher05095 天前
Hive核心知识:从基础到实战全解析
数据仓库·hive·hadoop
xhaoDream5 天前
Hive3.1.3 配置 Tez 引擎
大数据·hive·tez