- group by - having
group by 【表示经过哪一个或者哪些字段进行分组】mysql
select max(sal) from emp group by job;
以上语句,先按照job分组,而后对每一组使用max(sal)求最高薪水web
select job,max(sal) from emp group by job;
重点:若一条DQL语句中有group by 字句,那么select关键字后面只能跟参与分组的字段和分组函数。sql
select deptno,avg(sal) as avgsal from emp group by deptno;
±-------±------------+
| deptno | avgsal |
±-------±------------+
| 20 | 2175.000000 |
| 30 | 1566.666667 |
| 10 | 2916.666667 |
±-------±------------+svg
select deptno,job,max(sal) from emp group by deptno,job;
select job,max(sal) from emp where job<>'MANAGER' group by job;
having和where功能相同,都是为了 完成数据的过滤。二者后面都是添加条件。
where在group by 以前完成过滤;
having在group by以后完成过滤。函数
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。spa
select…
from …
where…
group by …
having …
order by…设计
第一:以上的关键字顺序不能变,严格遵照
第二:执行顺序:
一、from 从某张表中检索数据
二、where 通过某条件进行过滤
三、group by 而后分组
四、having 分组以后不满意的在过滤
五、select查询出来
六、order by 排序输出code
-sql92
-sql99【主要掌握】xml
-内链接: 等值链接 \ 非等值链接 \ 自链接
-外链接:左外链接\右外连接
-全链接【使用不多】排序
案例:查询每个员工所在部门的名称,要求最终显示员工名和对应部门名。
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)
结论:若两张表进行链接查询的时候,没有任何条件限制,最终查询结果总数老是两张表记录条数乘积,这种现象被称为笛卡尔积现象。为了不笛卡尔积现象的发生,必须在表连接的时候添加限制条件。
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)
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 |
±-------±--------±------+
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 |
±--------±-----------+
内链接:
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。若存在,表示必定是一个外链接,其余都是内链接;
-加上去的好处是加强可读性。
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)
多张表格进行表链接的语法格式:
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 |
±-------±------------±------+
-select语句嵌套select语句
select...(select), from.....(select),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 |
±------±--------+
案例:找出每个部门的平均薪水,而且要求显示平均薪水的薪水等级
第一步:找出每一个部门的平均薪水
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 |
±------------±------+
select e,ename,(select d,dname from dept d where e.deptno=d.deptno) as dname from emp e;
4、union