date: 2019-03-22 17:02:37

updated: 2020-04-08 16:00:00

Hive Sql的日常使用笔记

1. distinct 和 group by

distinct 只能返回去重的列

group by 理论上是需要在 select 后面配合聚合函数(sum, avg, max, min, count)来使用的

select 后面没有在聚合函数中的列都需要写在 group by 的后面,eg:

select A1, A2, A3, max(B) from test group by A1, A2, A3

select distinct(A), B from testselect distinct A, B from test 返回的是一样的,返回的都是 A 和 B 的组合值没有重复的结果

如果需要去重的话,select 需要的列 from A, (select min(主键) from A group by 要去重的列)B where A.主键 = B.主键

2. left join

A left join B on A.a1 = B.b and A.a2 = 'val' 保留 A 的所有结果,同时 on 后面的结果只针对这一条 left join 语句,不会影响最后的筛选,所以如果要保留所有 A.a2 = 'val' 的数据的话,应该在最后写 where A.a2 = 'val'

3. if 和 case when

一层: if(A.a = 'key', val1, val2)

两层: if(A.a = 'key1', val1, if(A.a = 'key2', val2, val3))

case A.a
when 'key1' then 'val1'
when 'key2' then 'val2'
else 'val3'
end

4. regexp_replace

替换掉 A.a 字段中的点 regexp_replace(A.a, "\\.", "")

5. cast

cast(A.a as int)

6. concat

concat(A.a,'-01-01')

7. concat_ws 行转列

concat_ws('/', collect_set(label_name))label_name group by key

concat 会自动把参数转换为字符串进行拼接,但是 concat_ws 需要提前将数值 cast 成字符串

8. regexp

where trim(A.a) regexp '^[1-9 | A-E]'

9. from_unixtime

from_unixtime(unix_timestamp(),'yyyy-MM-dd hh:mm:ss') update_time

10. 索引

索引基数: 数据列所包含的不同值的数量。索引的基数相对于数据表行数较高(即列中包含很多不同的值,重复的值很少),这个时候创建的索引效果更好。因为查询优化器如果发现某个值出现在表的数据行中的百分比很高的时候,可能会忽略索引直接进行全盘扫描。

11. row_number()

row_number() over(partition by 主键 order by 字段1 desc)as r

12.多个条件

if(boolean, res1, if(boolean, res2, if(boolean, res3,……)))

13.nvl

nvl(a,b) 如果a为null 那就取b 只能判断null 不能判断空

14.decimal

cast(round((sum(an) * 100 / sum(tn)),2) as decimal(20,2))

round((sum(an) * 100 / sum(tn)),2) 可能会出现 84.6599999999 的数据,可能只是 hue 上的 bug,需要再处理一下

15.补零

if(substr(bp, 1, 1) != 'X' and bp is not null and trim(bp) != 'null' and trim(bp) != '' and trim(bp) != '*', lpad(bp, 10, '0'), bp)as temp

16.推数编码出错

Incorrect string value: '\xF0\xAF\xA0\xA5' for column 'customer_txt' at row 45

以下几种方法有可能可以解决:

  1. 修改字符集为 utf8mb4
  2. --default-character-set gbk 在 sqoop 最后转换为 gbk 编码
  3. 出错原因是 can't parse data ' ' 之类的话,可能是因为特殊字符,需要一个个排查,可以试一下 regexp_replace(field,'\0','')

17.去重

select distinct t1.objnr
from jest t1
where t1.stat = 'I0002'
and t1.objnr not in (select distinct objnr from jest where stat = 'I0076'); ==> select * from
(select objnr, min(if(stat = 'I0002', 0, 1))a, max(if(stat = 'I0076', 1, 0))b
from jest group by objnr)t where t.a = 0 and t.b = 1;

18.插入数据

insert into table values ('05:00','6') ,('06:00','7'),
('07:00','8'), ('08:00','9'), ('09:00','10'), ('10:00','11'), ('11:00','12'), ('12:00','13'),
('13:00','14');

19.每隔N小时取数分组求和

通过截取字符串,获取时间,除以N保留整数位,分组

20.正则表达式的匹配

select regexp_replace('[3]','[','a')	不识别
select regexp_replace('[3]','\[','a') 不识别
select regexp_replace('[3]','\\[','a') 识别
select regexp_replace('[3]',']','a') 识别
select regexp_replace('[3]','\]','a') 识别
select regexp_replace('[3]','\\]','a') 识别
select regexp_replace('[3,.]',',','a') 识别
select regexp_replace('[3,.]','.','a') aaaaa .会识别为通配符,即所有字符
select regexp_replace('[3,.]','\.','a') 不识别
select regexp_replace('[3,.]','\\.','a') [3,a] 识别

21.空字符串关联

  1. (NULL) 在 join on 的时候不会被关联出来
  2. '' ' ' 在 join on 的时候会相互关联,只要有匹配项就会关联出来
  3. (NULL) 只在 left jion 的时候可以出来

22.lateral view explode 列转行

select gid, assist
from origin_ennenergy_intelligent_operation.wo_baseinfo
lateral view explode
(split(split(split(regexp_replace(assist_man, '"',""), "\\[")[1],"\\]")[0], ",")) aa as assist

23. userids 包含 gid

find_in_set(gid, userids)  # userids 需要用逗号分隔
instr(userids, gid) 会让 ('2,11', '1') 也被筛选出来

24.pmod(a, b) 取模(取余)运算

pmod(7, 4) -> 3
pmod(9, -4) -> -3
# 9 mod -4 商可以取 -2 或 -3,因为 -3 < -2,所以商取 -3,-4 * -3 = 12, 9 - 12 = -3,所以最终结果是 -3
pmod(-9, 4) -> 3
# -9 mod 4 商可以取 -2 或 -3,因为 -3 < -2,所以商取 -3,4 * -3 = -12, -9 - (-12) = 3,所以最终结果是 3

25.insert 和 insert overwrite

insert overwrite 本质是先覆盖原先的表,再把新的数据插入

26.insert 和 insert into

insert table user(id, name) values(1, 'zhangsan');

insert into table user values(1, 'zhangsan');

27.max(if) 或者 max(case when) 行转列

select id,
max(if(name = 'buss', pass, '')) as buss,
max(if(name = 'record', pass, '')) as record,
max(if(name = 'stock', pass, '')) as stock,
max(if(name = 'client', pass, '')) as client
from test0610
group by id; select id,
MAX(CASE WHEN name = 'buss' THEN pass END) AS buss,
MAX(CASE WHEN name = 'record' THEN pass END) AS record,
MAX(CASE WHEN name = 'stock' THEN pass END) AS stock,
MAX(CASE WHEN name = 'client' THEN pass END) AS client
from test0610
group by id;

28.复制表结构 但不复制数据

create table Test2 like Test1;

29.两个限制条件

要让每一条数据都满足 balance < 0,gas > 0,转换成 count(if(balance >= 0, 1, 0)) as a, count(if(gas <= 0, 1, 0)) as b,然后 where 中取 a = 0 and b = 0 的数据

30.join优化

  1. 多表join,其中有一个是最大的表
select /*+ STREAMTABLE(table1) */ tabl1.a, table1.b, table2.c
from table1 join table2 on ......

hive会假定查询中最后一个表是最大的表。在对每行记录进行连接操作的时候,会尝试将其他表缓存起来,然后扫描最后那个表进行计算。通过 /*+ STREAMTABLE(table1) */ 可以显式地指出最大的表是哪一个,hive会将其作为驱动表,哪怕它不是在 join 的最后面

  1. 多表join,其中有一个是最小的表
select /*+ MAPJOIN(table1) */ tabl1.a, table1.b, table2.c
from table1 join table2 on ......

如果所有表中只有一张表是小表,那么可以在最大的表通过mapper的时候将小表完全放到内存中。Hive可以在map端执行连接过程(称为map-side JOIN),这是因为hive可以和内存中的小表进行逐一匹配,从而省略掉常规连接操作所需要的reduce过程。

31.导出mysql数据库的注释

SELECT
COLUMN_NAME 列名,
COLUMN_TYPE 数据类型,
DATA_TYPE 字段类型,
CHARACTER_MAXIMUM_LENGTH 长度,
IS_NULLABLE 是否为空,
COLUMN_DEFAULT 默认值,
COLUMN_COMMENT 备注
FROM
INFORMATION_SCHEMA.COLUMNS
table_schema = '库名'
AND
-- 如果不写的话,默认会查询出所有表中的数据,这样可能就分不清到底哪些字段是哪张表中的了,所以还是建议写上要导出的名名称
table_name = '表名'

32. count()

count(*):所有行进行统计,包括NULL行
count(1):所有行进行统计,包括NULL行
count(column):统计column所有非NULL行

33. sum(if...) 和 count(if...)

在计数的时候,以下两种方式是等效的:

sum(if(条件判断, 1, 0))

count(if(条件判断, 字段, NULL))

原因在于 NULL 并不参加任何计算(但是升序排序的时候 NULL 是第一个,因为ASC码最小)。

34. sum() over(...)

sum() over(partition by year) 计算结果是按照 year 分组来 sum 的总和
sum() over(partition by year order by month) 计算结果是按照 year 分组,1月算的是1月的和,2月算的是 1 - 2月的和, 3月算的是 1 - 3月的和

同理适用于其他的窗口函数

35. count(distinct a) 不支持窗口函数,即不支持后面跟着 over(partiton by 1)

36. size 函数 返回后面map或者array里面的元素个数

size(collect_set(字段)) over(partiton by 1)

37. 设置变量

set myvar = "test";
select ${hiveconf:myvar}

38. coalesce() 函数

依次查看每一个表达式,返回第一个非空值,如果都是空,最后返回空值

coalesce(expression_1, expression_2, ...,expression_n)

39. count(distinct) 优化

直接使用 count(distinct) 会把数据放入到一个 reducer 下进行计算,导致运行缓慢。

比如统计本月活跃用户个数

优化一:

-- 外层SELECT求和
SELECT
SUM(mau_part) mau
FROM
(
-- 内层SELECT分别进行COUNT(DISTINCT)计算
SELECT
substr(uuid, 1, 3) uuid_part,
COUNT(DISTINCT substr(uuid, 4)) AS mau_part
FROM detail_sdk_session
WHERE partition_date >= '2020-01-01' AND partition_date <= nowdate
GROUP BY substr(uuid, 1, 3)
) t; ∵ uuid 是唯一的 ∴ 最后的结果 每个uuid_part对应的mau_part都是1,最后求和就是用户总数 这个写法的好处是,利用 group by 将数据分散到不用的 reducer 进行 count(distinct)计算,提高查询效率

这里 uuid 只截取了3位,如果截取位数过多,假设 uuid 长度为30位,内层 group by 会产生 30^n 个分组,那么外层也需要进行 30^n 次求和

优化二:

--  第三层SELECT
SELECT
SUM(s.mau_part) mau
FROM
(
-- 第二层SELECT
SELECT
tag,
COUNT(*) mau_part
FROM
(
-- 第一层SELECT
SELECT
uuid,
CAST(RAND() * 100 AS BIGINT) tag -- 为去重后的uuid打上标记,标记为:0-100之间的整数。
FROM detail_sdk_session
WHERE partition_date >= '2020-01-01'
AND partition_date <= nowdate
AND uuid IS NOT NULL
GROUP BY uuid -- 通过GROUP BY,保证去重
)t
GROUP BY tag
)s; 第一层SELECT:对uuid进行去重,并为去重后的uuid打上整数标记
第二层SELECT:按照标记进行分组,统计每个分组下uuid的个数
第三层SELECT:对所有分组进行求和

如果数据量确实很大,也可以增加分组的个数。例如:CAST(RAND() * 1000 AS BIGINT) tag

Hive Sql的日常使用笔记的更多相关文章

  1. Hive sql & Spark sql笔记

    记录了日常使用时遇到的特殊的查询语句.不断更新- 1. SQL查出内容输出到文件 hive -e "...Hive SQL..." > /tmp/out sparkhive ...

  2. SQL反模式学习笔记9 元数据分裂

    目标:支持可扩展性.优化数据库的结构来提升查询的性能以及支持表的平滑扩展. 反模式:克隆表与克隆列 1.将一张很长的表拆分成多张较小的表,使用表中某一个特定的数据字段来给这些拆分出来的表命名. 2.将 ...

  3. Android:日常学习笔记(9)———探究持久化技术

    Android:日常学习笔记(9)———探究持久化技术 引入持久化技术 什么是持久化技术 持久化技术就是指将那些内存中的瞬时数据保存到存储设备中,保证即使在手机或电脑关机的情况下,这些数据仍然不会丢失 ...

  4. Android:日常学习笔记(10)———使用LitePal操作数据库

    Android:日常学习笔记(10)———使用LitePal操作数据库 引入LitePal 什么是LitePal LitePal是一款开源的Android数据库框架,采用了对象关系映射(ORM)的模式 ...

  5. SQL Server技术内幕笔记合集

    SQL Server技术内幕笔记合集 发这一篇文章主要是方便大家找到我的笔记入口,方便大家o(∩_∩)o Microsoft SQL Server 6.5 技术内幕 笔记http://www.cnbl ...

  6. 【hive】——Hive sql语法详解

    Hive 是基于Hadoop 构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop 分布式文件系统中的数据,可以将结构 化的数据文件映射为一张数据库表,并提供完整的SQL查 ...

  7. SQL Server 2012 数据库笔记

    慕课网 首页 实战 路径 猿问 手记     Python 手记 \ SQL Server 2012 数据库笔记 SQL Server 2012 数据库笔记 2016-10-25 16:29:33 1 ...

  8. Hive SQL 监控系统 - Hive Falcon

    1.概述 在开发工作当中,提交 Hadoop 任务,任务的运行详情,这是我们所关心的,当业务并不复杂的时候,我们可以使用 Hadoop 提供的命令工具去管理 YARN 中的任务.在编写 Hive SQ ...

  9. hive sql 语法详解

    Hive 是基于Hadoop 构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop 分布式文件系统中的数据,可以将结构 化的数据文件映射为一张数据库表,并提供完整的SQL查 ...

随机推荐

  1. MyBatis常用实现方式

    MyBatis 是一个优秀的基于 java 的持久层框架,它内部封装了 jdbc,使开发者只需要关注 sql 语句本身,而不需要花费精力去处理加载驱动.创建连接.创建 statement 等繁杂的过程 ...

  2. 快速上手spring

    一.初始程序 1.在父类pom导入所需要的jar包 2.编写一个实体类 3.创建一个beans.xml,创建一个bean即创建一个user对象,可在bean内配置property即设置属性值 4.用测 ...

  3. 你想要的Java资料这里都有!!!

    你想要的Java资料这里都有!!!  [复制链接]       1.资源标题:程序员的SQL金典(完整) 资源地址:http://down.51cto.com/data/2207566 2.资源标题: ...

  4. xss利用——BeEF#stage2(初始并持续化控制)

    全文概览 浏览器攻击方法流程 攻击浏览器一般分为几个阶段,如下图 整个过程分为三个步骤,第一步是初始化控制,第二步是持续控制,第三步是攻击.在第三步中的七个攻击方法是可以交叉的,比如可以同时攻击用户和 ...

  5. win10病毒和威胁防护无法重新启动解决方法

    1.检查电脑中是否安装了任何的第三方反病毒软件 (例如 360.腾讯电脑管家等)?如果有的话,麻烦您将其卸载,卸载完毕后重启设备,再看一下病毒和威胁防护能否正常启动:2.按 "Windows ...

  6. Centos-显示文件类型-file

    file 长度为0的文件则显示为空位文件,对于软链接文件则显示链接的真实文件路径,默认输出会有文件名 相关选项 -b 只显示文件类型结果 -L 显示软链接指向文件的类型 -z 显示压缩文件信息 -i ...

  7. 关于Python中以字母r,或字母u 开头的字符串

      (1)以r或R开头的Python中的字符串表示(非转义的)原始字符串 python里面的字符,如果开头处有个r,比如: (r'^time/plus/\d{1,2}/$', hours_ahead) ...

  8. #error: Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD[d]

    转载:https://www.cnblogs.com/cvwyh/p/10570920.html 错误 在使用VS编译文件时出现了如下错误: #error: Building MFC applicat ...

  9. Arduino读取写入电压值

    读取写入方式分为数字和模拟 读取方式:(注意接地) 数字:digitalRead(pin); 模拟:analogRead(A1);float val=value*(5.0/1023.0);       ...

  10. c语言 static的用法

    static在c里面可以用来修饰变量,也可以用来修饰函数.先看用来修饰变量的时候.变量在c里面可分为存在全局数据区.栈和堆里.其实我们平时所说的堆栈是栈而不是堆,不要弄混.int a ;int mai ...