mysql查询
- 一、分组查询
- 1、分组查询设计的两个字句:
- 2、group by
- 2.1 order by 【表示通过哪个或者哪些字段进行排序】
- 2.2 案例:找出每个工作岗位的最高薪水【先按照工作岗位分组,使用max函数求每一组的最高薪水】
- 2.3 案例:计算每个部门的平均薪水【按部门编号分组,对每一组求平均薪水】
- 2.4 案例:计算不同部门不同岗位的最高薪水
- 2.5 案例:找出每个岗位的最高薪水,除去岗位为 MANAGER 的部分。
- 3、having
- 3.1案例:找出每个工作岗位的平均薪水。要求显示平均薪水大于1500。
- 4、 一个完整的DQL语句总结:
- 二、连接查询
- 1、连接查询根据出现的年代分类:
- 2、连接查询根据连接方式分类:
- 3、当多张表进行连接查询,若没有任何条件进行限制,会发生什么现象?
- 4、案例:查询每一个员工所在部门的名称,要求最终显示员工名和对应部门名。
- 5、案例:找出每一个员工对应的工资等级,要求显示员工名,工资,工资等级等。
- 6、案例:找出每一个员工的上级领导,要求显示员工名以及对应的领导名。
- 7、案例:找出每个员工对应的部门名称,要求部门名称全部显示。
- 8、案例:找出每一个员工对应的领导名,要求显示所有的员工。
- 9、案例:找出每一个员工对应的部门名称,以及该员工对应的工资等级。要求显示员工名、部门名、工资等级。
- 三、子查询
- 1、什么是子查询?
- 2、子查询可以出现在哪里?
- 3、where 后面使用select子查询
- 4、from后面使用子查询【小窍门:将查询结果当作临时表】
- 5、在select后面使用子查询【了解即可】
一、分组查询
1、分组查询设计的两个字句:
- group by
- having
2、group by
2.1 order by 【表示通过哪个或者哪些字段进行排序】
group by 【表示通过哪个或者哪些字段进行分组】
2.2 案例:找出每个工作岗位的最高薪水【先按照工作岗位分组,使用max函数求每一组的最高薪水】
select
max(sal)
from
emp
group by
job;
以上语句,先按照job分组,然后对每一组使用max(sal)求最高薪水
select
job,max(sal)
from
emp
group by
job;
重点:若一条DQL语句中有group by 字句,那么select关键字后面只能跟参与分组的字段和分组函数。
2.3 案例:计算每个部门的平均薪水【按部门编号分组,对每一组求平均薪水】
select deptno,avg(sal) as avgsal from emp group by deptno;
±-------±------------+
| deptno | avgsal |
±-------±------------+
| 20 | 2175.000000 |
| 30 | 1566.666667 |
| 10 | 2916.666667 |
±-------±------------+
2.4 案例:计算不同部门不同岗位的最高薪水
select deptno,job,max(sal) from emp group by deptno,job;
2.5 案例:找出每个岗位的最高薪水,除去岗位为 MANAGER 的部分。
select job,max(sal) from emp where job<>'MANAGER' group by job;
3、having
having和where功能相同,都是为了 完成数据的过滤。两者后面都是添加条件。
where在group by 之前完成过滤;
having在group by之后完成过滤。
3.1案例:找出每个工作岗位的平均薪水。要求显示平均薪水大于1500。
select job,avg(sal) from emp where avg(sal)>1500 group by job;
ERROR 1111 (HY000): Invalid use of group function
原因:where关键字后面不能直接使用分组函数,分组函数必须在分组完成后执行
mysql> select job,avg(sal) from emp group by job having avg(sal)>1500;
±----------±------------+
| job | avg(sal) |
±----------±------------+
| MANAGER | 2758.333333 |
| ANALYST | 3000.000000 |
| PRESIDENT | 5000.000000 |
±----------±------------+
原则:由于两个函数的效率不同问题,尽量在where 中过滤,无法过滤的数据,通常先分组之后在过滤,这时候可以选择使用having。
4、 一个完整的DQL语句总结:
select…
from …
where…
group by …
having …
order by…
第一:以上的关键字顺序不能变,严格遵守
第二:执行顺序:
1、from 从某张表中检索数据
2、where 经过某条件进行过滤
3、group by 然后分组
4、having 分组之后不满意的在过滤
5、select查询出来
6、order by 排序输出
二、连接查询
1、连接查询根据出现的年代分类:
-sql92
-sql99【主要掌握】
2、连接查询根据连接方式分类:
-内连接: 等值连接 \ 非等值连接 \ 自连接
-外连接:左外连接\右外链接
-全连接【使用很少】
3、当多张表进行连接查询,若没有任何条件进行限制,会发生什么现象?
案例:查询每一个员工所在部门的名称,要求最终显示员工名和对应部门名。
emp 员工表
±-------±-------+
| ename | deptno |
±-------±-------+
| SIMITH | 20 |
| ALLEN | 30 |
| WARD | 30 |
| JONES | 20 |
| MARTIN | 30 |
| BLAKE | 30 |
| CLARK | 10 |
| SCOTT | 20 |
| KING | 10 |
| TURNER | 30 |
| ADAMS | 20 |
| JAMES | 30 |
| FORD | 20 |
| MILLER | 10 |
±-------±-------+
dept部门表
±-------±------------+
| deptno | dname |
±-------±------------+
| 10 | ACCOUNTING |
| 20 | RESEARCHING |
| 30 | SALES |
| 40 | OPERATIONS |
±-------±------------+
主要分析:多张表连接查询,若没有任何条件进行限制,会发生什么现象?
小知识点:在进行夺标联合查询时,尽量给表起别名。这样可读性高。
select e.ename,d.dname from emp e ,dept d;
±-------±------------+
| ename | dname |
±-------±------------+
| SIMITH | ACCOUNTING |
| SIMITH | RESEARCHING |
| SIMITH | SALES |
| SIMITH | OPERATIONS |
| ALLEN | ACCOUNTING |
| ALLEN | RESEARCHING |
| ALLEN | SALES |
| ALLEN | OPERATIONS |
…
56 rows in set (0.00 sec)
结论:若两张表进行连接查询的时候,没有任何条件限制,最终查询结果总数总是两张表记录条数乘积,这种现象被称为笛卡尔积现象。为了避免笛卡尔积现象的发生,必须在表链接的时候添加限制条件。
4、案例:查询每一个员工所在部门的名称,要求最终显示员工名和对应部门名。
sql92语法:内连接中的等值连接
mysql> select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno;
sql99语法:内连接中的等值连接
sql99语法的优点:表连接独立出来了,结构清晰,对表连接不满意的话,可以再追加where进行过滤。
select e.ename,d.dname from emp e join dept d on e.deptno=d.deptno;
±-------±------------+
| ename | dname |
±-------±------------+
| SIMITH | RESEARCHING |
| ALLEN | SALES |
| WARD | SALES |
| JONES | RESEARCHING |
| MARTIN | SALES |
| BLAKE | SALES |
| CLARK | ACCOUNTING |
| SCOTT | RESEARCHING |
| KING | ACCOUNTING |
| TURNER | SALES |
| ADAMS | RESEARCHING |
| JAMES | SALES |
| FORD | RESEARCHING |
| MILLER | ACCOUNTING |
±-------±------------+
14 rows in set (0.01 sec)
5、案例:找出每一个员工对应的工资等级,要求显示员工名,工资,工资等级等。
sql92语法:内连接中的非等值连接
select e.ename,s.grade from emp e ,salgrade s where e.sal>=s.losal and e.sal<= s.hisal;
sql99语法:内连接中的非等值连接
select e.ename,e.sal, s.grade from emp e inner join salgrade s on e.sal betwee
n s.losal and s.hisal; //inner可以省略
±-------±--------±------+
| ename | sal | grade |
±-------±--------±------+
| SIMITH | 800.00 | 1 |
| ALLEN | 1600.00 | 3 |
| WARD | 1250.00 | 2 |
| JONES | 2975.00 | 4 |
| MARTIN | 1250.00 | 2 |
| BLAKE | 2850.00 | 4 |
| CLARK | 2450.00 | 4 |
| SCOTT | 3000.00 | 4 |
| KING | 5000.00 | 5 |
| TURNER | 1500.00 | 3 |
| ADAMS | 1100.00 | 1 |
| JAMES | 950.00 | 1 |
| FORD | 3000.00 | 4 |
| MILLER | 1300.00 | 2 |
±-------±--------±------+
6、案例:找出每一个员工的上级领导,要求显示员工名以及对应的领导名。
sql92语法:内连接中的自连接
select a.ename empname, b.ename leadername from emp a , emp b where a.mgr=b.empno;
sql99语法:内连接中的自连接
select a.ename empname, b.ename leadername from emp a inner join emp b on a.mgr=b.empno;//inner可以省略
±--------±-----------+
| empname | leadername |
±--------±-----------+
| SIMITH | 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 |
±--------±-----------+
7、案例:找出每个员工对应的部门名称,要求部门名称全部显示。
内连接:
A表和B表能够完全匹配的记录查询出来,被称为内连接;
外连接:【只掌握SQL99语法】
A表和B表能够完全匹配的记录查询出来之外,将其中一张表的记录全部无条件能查询出来,对方表没有匹配的记录,会自动模拟出NULL与之匹配,这种查询被称为外连接。
外连接的查询结果条数>=内连接的查询结果条数
sql99语法:外连接中的右外连接【右连接】
select e.ename,d.dname from emp e right outer join dept d on e.deptno=d.deptno;//outer可以省略
sql99语法:外连接中的左外连接【左连接】
select e.ename,d.dname from dept d left outer join emp e on e.deptno=d.deptno;//outer可以省略
任何一个右外连接都可以写成左外连接,任何一个左外连接也同样可以写成右外连接。
±-------±------------+
| ename | dname |
±-------±------------+
| SIMITH | RESEARCHING |
| ALLEN | SALES |
| WARD | SALES |
| JONES | RESEARCHING |
| MARTIN | SALES |
| BLAKE | SALES |
| CLARK | ACCOUNTING |
| SCOTT | RESEARCHING |
| KING | ACCOUNTING |
| TURNER | SALES |
| ADAMS | RESEARCHING |
| JAMES | SALES |
| FORD | RESEARCHING |
| MILLER | ACCOUNTING |
| NULL | OPERATIONS |
±-------±------------+
为什么inner和outer可以省略,加上去有什么好处?
-可以省略,区分内外连接依靠的不是这些关键字,而是看SQL语句中是否存在left/right。若存在,表示一定是一个外连接,其他都是内连接;
-加上去的好处是增强可读性。
8、案例:找出每一个员工对应的领导名,要求显示所有的员工。
select a.ename empname,b.ename leadername from emp a left join emp b on a
.mgr=b.empno;
±--------±-----------+
| empname | leadername |
±--------±-----------+
| SIMITH | 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)
9、案例:找出每一个员工对应的部门名称,以及该员工对应的工资等级。要求显示员工名、部门名、工资等级。
多张表格进行表连接的语法格式:
select xxx from a join b on 条件 join c on 条件;
原理:a和b表进行表连接之后,a表再和c表进行表连接。
select e.ename,d.dname,s.grade from emp e join dept d on e.deptno=d.deptno join salgrade s on e.sal between s.losal and s.hisal;
±-------±------------±------+
| ename | dname | grade |
±-------±------------±------+
| SIMITH | RESEARCHING | 1 |
| ALLEN | SALES | 3 |
| WARD | SALES | 2 |
| JONES | RESEARCHING | 4 |
| MARTIN | SALES | 2 |
| BLAKE | SALES | 4 |
| CLARK | ACCOUNTING | 4 |
| SCOTT | RESEARCHING | 4 |
| KING | ACCOUNTING | 5 |
| TURNER | SALES | 3 |
| ADAMS | RESEARCHING | 1 |
| JAMES | SALES | 1 |
| FORD | RESEARCHING | 4 |
| MILLER | ACCOUNTING | 2 |
±-------±------------±------+
三、子查询
1、什么是子查询?
-select语句嵌套select语句
2、子查询可以出现在哪里?
select...(select), from.....(select),where....(select)
3、where 后面使用select子查询
案例:找出薪水比公司平均薪水高的员工,要求显示员工名和薪水。
select ename ,sal from emp where sal > avg(sal);
以上语句错误,分组函数不能直接使用在where后面。
第一步:找出公司的平均薪资;
select avg(sal) from emp;
第二步:找出薪水大于平均薪水的员工信息
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 |
±------±--------+
4、from后面使用子查询【小窍门:将查询结果当作临时表】
案例:找出每一个部门的平均薪水,并且要求显示平均薪水的薪水等级
第一步:找出每个部门的平均薪水
select deptno, avg(sal) as avgsal from emp group by deptno;
±-------±------------+
| deptno | avgsal |
±-------±------------+
| 20 | 2175.000000 |
| 30 | 1566.666667 |
| 10 | 2916.666667 |
±-------±------------+
第二步:将上面的查询结果当作临时表t,t表和salgrade s表进行表连接,条件:t.avgsal between s.losal and s.hisal;
select
t.deptno,t.avgsal,s.grade
from
t
join
salgrade s
on
t.avgsal between s.losal and s.hisal;
将t表换成第一步的执行结果即可。
select t.avgsal, s.grade from (select deptno, avg(sal) as avgsal from emp group by deptno) t join salgrade s on t.avgsal between s.losal and s.hisal;
±------------±------+
| avgsal | grade |
±------------±------+
| 2175.000000 | 4 |
| 1566.666667 | 3 |
| 2916.666667 | 4 |
±------------±------+
5、在select后面使用子查询【了解即可】
select e,ename,(select d,dname from dept d where e.deptno=d.deptno) as dname from emp e;
四、union