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. MySQL的共享锁阻塞会话案例浅析输入日志标题

        这是问题是一个网友遇到的问题:一个UPDATE语句产生的共享锁阻塞了其他会话的案例,对于这个案例,我进一步分析.总结和衍化了相关问题.下面分析如有不对的地方,敬请指正.下面是初始化环境和数据的 ...

  2. 刷题[BJDCTF 2nd]简单注入

    解题思路 打开发现登陆框,随机输入一些,发现有waf,然后回显都是同样的字符串.fuzz一波,发现禁了挺多东西的. select union 等 这里猜测是布尔盲注,错误的话显示的是:You konw ...

  3. vue学习04 v-on指令

    vue学习04 v-on指令 v-on的作用是为元素绑定事件,比如click单击,dbclick双击 v-on指令可简写为@ 代码测试 <!DOCTYPE html> <html l ...

  4. Spring学习(四)--Spring的IOC

    1.BeaDefinition的Resource定位 (1)直接使用BeanDefinitionFactory 定义一个Resource来定位容器使用的BeanDefinition. Resource ...

  5. Python 中的是那种路径

    1.1 操作系统文件绝对路径 django 静态文件查找, 模板查找(第一种)   # 去配置好的 文件夹 中查找指定的文件 BASE_DIR = os.path.dirname(os.path.di ...

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

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

  7. python中的filter、map、reduce、apply用法总结

    1. filter 功能: filter的功能是过滤掉序列中不符合函数条件的元素,当序列中要删减的元素可以用某些函数描述时,就应该想起filter函数. 调用: filter(function,seq ...

  8. P4568 [JLOI2011]飞行路线 / P2939 [USACO09FEB]Revamping Trails G

    题目描述 Link Alice 和 Bob 现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在 \(n\) 个城市设有业务,设这些城市分别标记为 \(0\) 到 \(n-1\),一共 ...

  9. TP5隐藏入口文件

    1,进入根目录,打开public文件夹,里面有个.htaccess文件 2,将这段代码改成?s= 3,不修改该文件,想要隐藏入口文件则会报错 4,改了文件之后是 5,改了入口文件为了隐藏  .php

  10. mysql任意文件读取漏洞复现

    前言 第一次得知该漏洞后找了一些文章去看. 一开始不明白这个漏洞是怎么来的,只知道通过在服务端运行poc脚本就可以读取客户端的任意文件,直接找到网上准备好的靶机进行测试,发现可行,然后就拿别人的poc ...