关键字 | 作用 |
---|---|
distinct | 如果有多个字段,根据组合进行去重 |
all | 默认情况就是查询所有,可以省略 |
select 1 from table | 相当于给表增加了一列 |
where | 分组前过滤 |
having | 分组后过滤 |
order by | 全局有序,按照关键字去重分组,reduce置为1 |
distribute by | 结合sort by使用,指明按照什么进行分区 |
sort by | 底层根据reduce个数随机分成对应个有序小组 |
cluster by | distribute by 和sort by 关键字一样时可以用它代替,没啥用,鸡肋 |
join | 左右相连 |
union | 上下相连 |
limit n offset m | 限制查询个数, 从第m个开始数 |
from > join on > where > group by > having > select > distinct > union > order by > limit
知道执行顺序的非常重要,建议书写SQL时也可以按照这个顺序来书写。不过select 建议在group by后即可书写了,因为必须先确定字段后才能进行分组后的排序。
当select查询的字段和group by后的字段一样时,本质上就是去重。如果不想缺失数据时,建议不要使用group by 关键字来进行分组。
如果不写on条件,join操作就是两个表进行逐行拼接,即笛卡尔积。join可以使用等值连接或者非等值连接。join默认是内连接,只会取符合on条件的交集。
满外连接: select * from emp e full join dept d on e.deptno = d.deptno;
union all 是上下两表连接不去重,union会默认去重。
优化前:先启动一个MR将a表和b表进行连接,之后将将连接结果再用一个MR和c表进行连接。
优化后:默认是开启优化的,会使用map join,将b表和c表都作为小表读入内存后,直接一个map过程完成连接操作。
order by deptno, salary 基本上等价于distribute by deptno sort by salary ,不过distribute by + sort by
效率更高,并且设置多个reduce时可以将数据分到不同的文件中。
show functions;
desc function 函数名
desc function extended 函数名
单行函数指每行数据处理一次,一进一出。
regexp_replace(str, regx, rep)
: 正则替换nvl(A, B)
: 如果A为null, 则赋值为Bdatediff(date1, date2)
: 计算日期的差值date_add()
: 日期的加减date_format()
:日期格式转换, 一般用于日期的截取if(a,b,c)
,如果a为真,则执行b,否则执行ccase
when sal >= 2500 then '小康'
when sal >=1500 and sal <2500 then '温饱'
when sal < 1500 then '贫穷'
end
多行函数指多行数据处理一次,多进一出
。collect_set(job)
: 收集分组后的去重数据集array_contains(arr, num)
: 判断数组中是否包含num元素炸裂函数指一行数据返回多个结果,一进多出。
select
*
from movie
lateral view explode(movies)
temp as movie;
rows between
表示 : 显示限定范围,默认是上无边界,下无边界
unbounded preceding
上无边界current row
当前行unbounded following
下无边界1 preceding
上一行1 following
下一行select
user_name,
order_date,
order_amount,
count(*)over(rows between
unbounded preceding and
unbounded following) cnt
from
order
(2) partition by 属性名…, 开窗后再划分子窗口,每行再单独计算。可以有多个属性名来通过组合来划分的更细。
(3) order by 属性名…, 对细分子窗口进行排序。
select
user_name,
order_date,
order_amount,
sum(order_amount)over(partition by user_name order by order_date)
from order_info;
6.1 跨行取数据
函数名 | 作用 |
---|---|
lag(字段名, 偏移量, 默认值) | 从当前位置向上偏移几行后取值,默认偏移量是1,默认值默认是null |
lead(字段名, 偏移量, 默认值) | 从当前位置向下偏移几行取值, 默认偏移量是1,默认值是默认是null |
6.2 取第一个和最后一个数据
函数名 | 作用 |
---|---|
first_value(字段名, false) | 取第一个数据,第二个参数表示是否忽略null |
last_value(字段名, false) | 取最后一个数据,一般第二个参数均为false |
6.3 排名函数
函数名 | 作用 |
---|---|
rank | 排名相同时会重复,有重复时下一个名次会消失,最后一个排名等于元素个数 |
dense_rank | 排名相同时会重复,有重复时下一个名次不会消失 |
row_number | 行号 |
6.4 分组分析
函数名 | 作用 |
---|---|
ntile(组的个数) | 将数据打上组名,可以通过组名取出对应组的数据 |
select
user_name,
order_date,
order_amount,
ntile(5)over(order by order_date) nt
from order_info;
注意:
①如果你需要结果有序,那一定要排序,否则会正进反出(MR的环形缓冲区的反向溢写导致的)
② 如果在累加求和时,排序有重复值,累加的不是一行,而是一段
位置 | 子查询类别 |
---|---|
select | 标量子查询 |
where | 标量子查询,列子查询 |
from | 行子查询, 列子查询 |