# 找出工资不等于3000的员工 select ename from emp where sal<>3000; # select ename from emp where sal!=3000; /* +--------+ | ename | +--------+ | SMITH | | ALLEN | | WARD | | JONES | | MARTIN | | BLAKE | | CLARK | | KING | | TURNER | | ADAMS | | JAMES | | MILLER | +--------+ 12 rows in set (0.00 sec) */
# 找出工资在1100到3000的员工 select ename from emp where sal between 1100 and 3000; # select ename from emp where sal>=1100 and sal<=3000; /* +--------+ | ename | +--------+ | ALLEN | | WARD | | JONES | | MARTIN | | BLAKE | | CLARK | | SCOTT | | TURNER | | ADAMS | | FORD | | MILLER | +--------+ 11 rows in set (0.00 sec) */
# 左小右大,左右闭区间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# 找出姓名首字母在A到C之间的员工 select ename from emp where ename between 'A' and 'D'; /* +-------+ | ename | +-------+ | ALLEN | | BLAKE | | CLARK | | ADAMS | +-------+ 4 rows in set (0.00 sec) */
# 取得普通员工(员工代码不在 mgr 字段上) select ename from emp where empno not in ( select mgr from emp where mgr is not null ); /* +--------+ | ename | +--------+ | SMITH | | ALLEN | | WARD | | MARTIN | | TURNER | | ADAMS | | JAMES | | MILLER | +--------+ */
like模糊查询
% 代表任意多个字符
_ 代表任意一个字符
1 2 3 4 5 6 7 8 9 10 11 12
# 找出名字当中有“O”的员工 select ename from emp where ename like '%O%'; /* +-------+ | ename | +-------+ | JONES | | SCOTT | | FORD | +-------+ 3 rows in set (0.00 sec) */
1 2 3 4 5 6 7 8 9 10 11 12
# 找出第二个字母是“A”的员工 select ename from emp where ename like '_A%'; /* +--------+ | ename | +--------+ | WARD | | MARTIN | | JAMES | +--------+ 3 rows in set (0.00 sec) */
1 2 3 4
# 找出名字中带有下划线的员工 select ename from emp where ename like '%\_%';
# 使用转义符
1 2 3 4 5 6 7 8 9 10 11 12
# 找出名字中最后一个字母是“T”的员工 select ename from emp where ename like '%T'; /* +-------+ | ename | +-------+ | SCOTT | +-------+ 1 row in set (0.00 sec) */
# 找出工资总和 select sum(sal) from emp; /* +----------+ | sum(sal) | +----------+ | 29025.00 | +----------+ 1 row in set (0.01 sec) */
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# 找出工资高于平均工资的员工(子查询) select ename, sal from emp where sal>(select avg(sal) from emp); /* +-------+---------+ | ename | sal | +-------+---------+ | JONES | 2975.00 | | BLAKE | 2850.00 | | CLARK | 2450.00 | | SCOTT | 3000.00 | | KING | 5000.00 | | FORD | 3000.00 | +-------+---------+ 6 rows in set (0.00 sec) */
group by 和 having
group by:按照某个字段或者某些字段进行分组
having:对分组之后的数据进行再次过滤
执行顺序:from -> where -> group by -> having -> select分组函数 -> order by
分组函数一般会与group by联合使用
sql语句没有group by,整张语句将会自成一组
当一条语句中有group by,select后面只能跟分组函数和分组的字段
在where中筛选条件比使用having效率更高
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# 找出每个工作岗位的最高薪资 select job, max(sal) from emp group by job; /* +-----------+----------+ | job | max(sal) | +-----------+----------+ | ANALYST | 3000.00 | | CLERK | 1300.00 | | MANAGER | 2975.00 | | PRESIDENT | 5000.00 | | SALESMAN | 1600.00 | +-----------+----------+ 5 rows in set (0.01 sec) */
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# 找出每个工作岗位的平均工资 select job, avg(sal) from emp group by job; /* +-----------+-------------+ | job | avg(sal) | +-----------+-------------+ | ANALYST | 3000.000000 | | CLERK | 1037.500000 | | MANAGER | 2758.333333 | | PRESIDENT | 5000.000000 | | SALESMAN | 1400.000000 | +-----------+-------------+ 5 rows in set (0.00 sec) */
# 效率过低,可以先筛除数据,再进行分组 # select deptno, max(sal) from emp group by deptno having max(sal)>2900;
# 效率高,优先考虑使用where过滤数据 select deptno, max(sal) from emp where sal>2900 group by deptno; /* +--------+----------+ | deptno | max(sal) | +--------+----------+ | 10 | 5000.00 | | 20 | 3000.00 | +--------+----------+ 2 rows in set (0.00 sec) */
1 2 3 4 5 6 7 8 9 10 11
# 找出每个部门的平均薪资,要求显示薪资大于2000的数据(where搞不定) select deptno, avg(sal) from emp group by deptno having avg(sal)>2000; /* +--------+-------------+ | deptno | avg(sal) | +--------+-------------+ | 10 | 2916.666667 | | 20 | 2175.000000 | +--------+-------------+ 2 rows in set (0.00 sec) */
完整的DQL语句
1 2 3 4 5 6 7 8 9 10 11 12
select 5 ... from 1 ... where 2 ... group by 3 ... having 4 ... order by 6 ...
查询结果集的去重
select后加上distinct关键字即可
distinct只能出现在所有字段前
1 2 3 4 5 6 7 8 9 10 11 12 13
select distinct job from emp; /* +-----------+ | job | +-----------+ | CLERK | | SALESMAN | | MANAGER | | ANALYST | | PRESIDENT | +-----------+ 5 rows in set (0.00 sec) */
1 2 3 4 5 6 7 8 9 10
# 统计岗位数量 select count(distinct job) from emp; /* +---------------------+ | count(distinct job) | +---------------------+ | 5 | +---------------------+ 1 row in set (0.00 sec) */
笛卡尔积现象
当两张表进行连接查询的时候,没有任何条件进行限制,最终的查询结果是两张表记录条数的乘积
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# 找出每一个员工的部门名称,要求显示员工名和部门名 select ename,dname from emp, dept; /* +--------+------------+ | ename | dname | +--------+------------+ | SMITH | ACCOUNTING | | SMITH | RESEARCH | | SMITH | SALES | | SMITH | OPERATIONS | | ALLEN | ACCOUNTING | | ALLEN | RESEARCH | | ALLEN | SALES | | ALLEN | OPERATIONS | ... 56 rows in set (0.01 sec) */
# 找出每一个员工的部门名称,要求显示员工名和部门名 # SQL92语法,以后不用 select e.ename, d.dname from emp e, dept d where e.deptno = d.deptno; /* +--------+------------+ | ename | dname | +--------+------------+ | CLARK | ACCOUNTING | | KING | ACCOUNTING | | MILLER | ACCOUNTING | | SMITH | RESEARCH | | JONES | RESEARCH | | SCOTT | RESEARCH | | ADAMS | RESEARCH | | FORD | RESEARCH | | ALLEN | SALES | | WARD | SALES | | MARTIN | SALES | | BLAKE | SALES | | TURNER | SALES | | JAMES | SALES | +--------+------------+ 14 rows in set (0.00 sec) */
# 找出每个员工的上级领导,要求显示员工名和对应的领导名 # 内连接跳过了King(最高领导) select a.ename as emp_name, b.ename as mgr_name from emp a inner join emp b on a.mgr = b.empno; /* +----------+----------+ | emp_name | mgr_name | +----------+----------+ | SMITH | FORD | | ALLEN | BLAKE | | WARD | BLAKE | | JONES | KING | | MARTIN | BLAKE | | BLAKE | KING | | CLARK | KING | | SCOTT | JONES | | TURNER | BLAKE | | ADAMS | SCOTT | | JAMES | BLAKE | | FORD | JONES | | MILLER | CLARK | +----------+----------+ 13 rows in set (0.00 sec) */
# 找出每个员工的上级领导,显示员工名和领导 # 外连接包含King(最高领导),显示为NULL select a.ename as emp_name, b.ename as mgr_name from emp a left join emp b on a.mgr = b.empno; /* +----------+----------+ | emp_name | mgr_name | +----------+----------+ | SMITH | FORD | | ALLEN | BLAKE | | WARD | BLAKE | | JONES | KING | | MARTIN | BLAKE | | BLAKE | KING | | CLARK | KING | | SCOTT | JONES | | KING | NULL | | TURNER | BLAKE | | ADAMS | SCOTT | | JAMES | BLAKE | | FORD | JONES | | MILLER | CLARK | +----------+----------+ 14 rows in set (0.03 sec) */
# 找出每个员工的上级领导,显示员工名和领导 # 外连接包含King(最高领导),显示为NULL select a.ename, b.ename from emp b right join emp a on a.mgr = b.empno; /* +--------+-------+ | ename | ename | +--------+-------+ | SMITH | FORD | | ALLEN | BLAKE | | WARD | BLAKE | | JONES | KING | | MARTIN | BLAKE | | BLAKE | KING | | CLARK | KING | | SCOTT | JONES | | KING | NULL | | TURNER | BLAKE | | ADAMS | SCOTT | | JAMES | BLAKE | | FORD | JONES | | MILLER | CLARK | +--------+-------+ 14 rows in set (0.00 sec) */
Puzzle
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# 找出哪个部门没有员工 select d.* from emp e right join dept d on d.deptno = e.deptno where e.deptno is null; /* +--------+------------+--------+ | DEPTNO | DNAME | LOC | +--------+------------+--------+ | 40 | OPERATIONS | BOSTON | +--------+------------+--------+ 1 row in set (0.01 sec) */
# 找出每个员工的部门名称、工资等级以及上级领导 select e.ename, d.dname, s.grade, e1.ename as mgr from emp e join dept d on e.deptno = d.deptno join salgrade s on e.sal between s.losal and s.hisal left join emp e1 on e.mgr = e1.empno; /* +--------+------------+-------+-------+ | ename | dname | grade | mgr | +--------+------------+-------+-------+ | SMITH | RESEARCH | 1 | FORD | | ALLEN | SALES | 3 | BLAKE | | WARD | SALES | 2 | BLAKE | | JONES | RESEARCH | 4 | KING | | MARTIN | SALES | 2 | BLAKE | | BLAKE | SALES | 4 | KING | | CLARK | ACCOUNTING | 4 | KING | | SCOTT | RESEARCH | 4 | JONES | | KING | ACCOUNTING | 5 | NULL | | TURNER | SALES | 3 | BLAKE | | ADAMS | RESEARCH | 1 | SCOTT | | JAMES | SALES | 1 | BLAKE | | FORD | RESEARCH | 4 | JONES | | MILLER | ACCOUNTING | 2 | CLARK | +--------+------------+-------+-------+ 14 rows in set (0.00 sec) */
子查询
select语句中嵌套select语句,被嵌套的select语句是子查询
子查询出现位置
select
…(select)…
from
…(select)…
where
…(select)…
where中嵌套子查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# 找出高于平均薪资的员工信息 select ename, sal from emp where sal > (select avg(sal) from emp); /* +-------+---------+ | ename | sal | +-------+---------+ | JONES | 2975.00 | | BLAKE | 2850.00 | | CLARK | 2450.00 | | SCOTT | 3000.00 | | KING | 5000.00 | | FORD | 3000.00 | +-------+---------+ 6 rows in set (0.00 sec) */
from中嵌套子查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# 不一定非要在from中嵌套子查询 # 找出每个部门平均薪水的等级 select t.*, s.grade from (select deptno, avg(sal) as avg_sal from emp group by deptno) t join salgrade s on t.avg_sal between s.losal and s.hisal; /* +--------+-------------+-------+ | deptno | avg_sal | grade | +--------+-------------+-------+ | 30 | 1566.666667 | 3 | | 10 | 2916.666667 | 4 | | 20 | 2175.000000 | 4 | +--------+-------------+-------+ 3 rows in set (0.00 sec) */
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# 找出每个部门平均的薪水等级 select e.deptno, avg(grade) as avg_grade from emp e join salgrade s on e.sal between s.losal and s.hisal group by e.deptno; /* +--------+-----------+ | deptno | avg_grade | +--------+-----------+ | 10 | 3.6667 | | 20 | 2.8000 | | 30 | 2.5000 | +--------+-----------+ 3 rows in set (0.00 sec) */
# 经典写法(or或in) # select ename,job from emp where job in('SALESMAN', 'MANAGER'); /* +--------+----------+ | ename | job | +--------+----------+ | ALLEN | SALESMAN | | WARD | SALESMAN | | JONES | MANAGER | | MARTIN | SALESMAN | | BLAKE | MANAGER | | CLARK | MANAGER | | TURNER | SALESMAN | +--------+----------+ 7 rows in set (0.01 sec) */
# union写法(结果一样但顺序不一样) select ename, job from emp where job='SALESMAN' union select ename, job from emp where job='MANAGER'; /* +--------+----------+ | ename | job | +--------+----------+ | ALLEN | SALESMAN | | WARD | SALESMAN | | MARTIN | SALESMAN | | TURNER | SALESMAN | | JONES | MANAGER | | BLAKE | MANAGER | | CLARK | MANAGER | +--------+----------+ 7 rows in set (0.01 sec) */
*limit
用作分页查询,取结果集中的部分数据
语法机制:limit [startIndex], [length]
startIndex表示起始位置
length表示取几个
MySQL特有(Oracle有相同的机制:rownum)
若只填一个数字,则默认startIndex为0
limit 是sql语句最后执行的一个环节
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# sql语句执行顺序 select 5 ... from 1 ... where 2 ... group by 3 ... having 4 ... order by 6 ... limit 7 ...;
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# 取出工资前5名的员工(思路:降序取前5个) select ename,sal from emp order by sal desc limit 0, 5; /* +-------+---------+ | ename | sal | +-------+---------+ | KING | 5000.00 | | SCOTT | 3000.00 | | FORD | 3000.00 | | JONES | 2975.00 | | BLAKE | 2850.00 | +-------+---------+ 5 rows in set (0.00 sec) */
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
# 找出工资排名在第4到第9名的员工? select ename, sal from emp order by sal desc limit 3, 6; /* +--------+---------+ | ename | sal | +--------+---------+ | JONES | 2975.00 | | BLAKE | 2850.00 | | CLARK | 2450.00 | | ALLEN | 1600.00 | | TURNER | 1500.00 | | MILLER | 1300.00 | +--------+---------+ 6 rows in set (0.00 sec) */