一、基础查询
1、全表查询:
select * from emp;
emp为员工表
dept为部门表
后续操作均为对以上两张表实现
2、别名:
通过as关键字定义别名,可加可不加;
select sal (as) s from emp (as) e;
3、Limit语句:
通过limit关键字限制查询行数:
select * from emp limit 5;
4、Where语句:
通过where关键字限制查询条件:
查询工资大于2000元的员工
select * from emp where sal > 2000;
5、distinct去重语句:
单列去重:
select distinct deptno from emp;
多列去重:
select distinct deptno,job from emp;
二、内置函数
1、数学函数
|
名称 |
符号 |
|
加减乘除 |
+ - * / |
|
四舍五入 |
round(n,保留位数) |
|
向上取整 |
ceil(n) |
|
向下取整 |
floor(n) |
|
随机生成0到1的数 |
rand() |
|
自然指数 |
exp(n) |
|
对数 |
log(n,m) |
|
幂函数 |
power(n,m) |
|
开方函数 |
sqrt(n) |
2、关系函数
|
名称 |
符号 |
|
等于 |
= |
|
不等于 |
<> 或者 != |
|
小于(等于) |
<(=) |
|
大于(等于) |
>(=) |
|
空值 |
is null |
|
非空值 |
is not null |
|
全包含 |
like |
|
半包含 |
rlike |
|
非全包含 |
not like |
3、字符串函数
|
名称 |
符号 |
|
长度 |
length("str") |
|
反转 |
reverse("str") |
|
concat连接 |
concat("str","-","str") |
|
concat_ws连接 |
concat_ws("-","str","str") |
|
截取 |
substr("str",int) |
|
转大写 |
upper("str") |
|
转小写 |
lower("str") |
4、逻辑函数
|
名称 |
符号 |
|
与 |
and |
|
或 |
or |
|
非 |
not |
5、日期函数
|
名称 |
语句 |
|
字符串转日期 |
select to_date('2019-10-1 09:02:20'); |
|
日期加法 |
select date_add('2019-10-1',3) |
|
日期减法 |
select date_sub('2019-10-1',3) |
|
转时间戳 |
select unix_timestamp('2019-10-15 09:28:20','yyyy-MM-dd HH:mm:ss'); |
|
时间戳减法 |
select unix_timestamp('2019-10-15 09:28:20','yyyy-MM-dd HH:mm:ss')- unix_timestamp('2019-10-15 09:27:20','yyyy-MM-dd HH:mm:ss'); |
|
时间戳转日期 |
select from_unixtime(1571102900,'yyyy-MM-dd HH:mm:ss'); |
6、聚合函数
|
名称 |
符号 |
|
求和 |
sum() |
|
最大值 |
max() |
|
最小值 |
min() |
|
个数统计 |
count() |
|
平均值 |
avg() |
注:当列名未命名时,需使用反单引号(esc键下面) ` 表示列名,如`_c1`
7、group by分组语句
常与聚合函数一起使用
查询每个部门的最低工资:
select deptno,min(sal) as sal_min from emp group by deptno;
8、全局排序order by
所有数据都在一个reducer里处理,不适合海量数据处理;
排序参数默认为升序asc,降序需设置为desc;
查询全表,按部门号升序,工资降序:
select * from emp order by deptno,sal desc;
9、局部排序sort by
分别对每个reducer都进行排序,所以整体不一定有序
通常结合distrubute by分区函数使用
设置reduce个数:
set mapreduce.job.reduces=3;
查看reduce个数
set mapreduce.job.reduces;
按部门号降序查询:
select * from emp sort by deptno desc;
可见查询出的结果整体并不有序.
10、分区distribute by:
在mapper端分簇再输出到reduce,但本身并无排序功能,所以结合sort by使用,要写在sort by之前
指定deptno作为分区键(未排序);
select * from emp distribute by deptno;
指定deptno作为分区键并按照sal升序排序;
select * from emp distribute by deptno sort by sal;
11、cluster by语句
cluster by 是 distribute by和sort by结合使用的结果,只能默认升序,分区和排序为同一个键;
select * from emp cluster by deptno;
三、多表查询
1、内连接join:
两个表都存在且条件匹配的数据才输出
查询每个部门员工的工作地址(下同):
select e.ename,d.deptno,d.loc from emp e join dept d on e.deptno = d.deptno;
上面为显式外连接,也可写作隐式:
select e.ename,d.deptno,d.loc from emp e,dept d e.deptno = d.deptno;
2、左外连接left join:
以左表为基准,右边符合条件匹配的数据保留,否则为null
select e.ename,d.deptno,d.loc from emp e left join dept d on e.deptno = d.deptno;
结果中不会包含部门号40及其地址
3、左半连接:
输出满足条件匹配的左表数据
select * from emp e left semi join dept d on e.deptno = d.deptno;
4、右外连接right join:
select e.ename,d.deptno,d.loc from emp e right join dept d on e.deptno = d.deptno;
结果中部门号40的员工名为null
5、全连接full join:
所有符合where条件的数据都会被保留,否则为null
select e.ename,d.deptno,d.loc from emp e full join dept d on e.deptno = d.deptno;
6、交叉连接查询:
select * from emp,dept;
得到的是两个表的乘积(笛卡尔积),有错误数据且冗余,基本不用
7、子查询(嵌套查询):
查询最低工资的员工姓名:
select m.min_sal,e.name from (select min(sal) min_sal from emp) as m, emp e where m.min_sale=e.sal;
8、控制语句case when
查询emp表中员工姓名,薪水,若薪水<=2000标记为low,2000<薪水<5000标记为middle,薪水>=5000标记为high:
select ename,sal, case when sal<= 2000 then 'low' when sal>2000 and sal<5000 then 'middle' else 'high' end as label from emp;
四、部分栗子
1、查询empno大于mgr中20号部门的员工姓名
create table t1 as select ename from emp_in where empno > mgr and deptno = 20;
2、查询带有奖金的所有员工的时薪(sal为月薪资),并保留2位小数
create table t2 as select cast(sal/30.0/24 as decimal(10,2)) sal_h from emp_in where comm is not NULL and comm != 0;
3、查询薪资TOP5的所有员工姓名s
create table t3 as select ename,sal from emp_in sort by sal desc limit 5;
4、求出薪资不在2000到3000区间的员工
create table t4 as select ename,sal from emp_in where sal<2000 or sal>3000;
5、查询姓名中带有'ER'姓名的所有员工数量、工资总和
create table t5 as select count(*) con,sum(sal) sum from emp_in where ename like '%ER%';
6、对不同部门的员工表按照薪资降序、员工号升序方式排列
create table t6 as select deptno,sal,empno from emp_in distribute by deptno sort by sal desc,empno;
7、查询各个部门中工资不高于3000的所有员工平均薪资
create table t7 as select avg(sal) as avg,deptno from emp_in where sal <= 3000 group by deptno;
8、查询出每个地区最高薪资的员工名称
create table t8 as select d.loc,e.sal,e.deptno,e.ename from emp_in as e,dept as d where d.deptno = e.deptno and e.sal in (select max(em.sal) from emp_in as em where e.deptno = em.deptno);