1.查询结果集的去重。
select
distinct job
from
emp;
distinct
关键字去除重复记录。
select
ename,distinct job
from
emp
这条SQL语句是错误的。
distinct
只能出现在所有字段的最前面。
select
distinct deptno,job
from
emp
这里则是deptno和job联合去重。
案例:统计岗位数量:
select count(distinct job) from emp;
2.连接查询
2.1
实际开发中,一般都是多张表联合进行查询。一个业务会对应多个表,多表联合使用可以减少数据的冗余。
内连接:
等值连接
非等值连接
自连接
外连接:
左外连接(左连接)
右外连接(右连接)
全连接
2.2
笛卡尔积现象
select ename,dname from emp,dept;
自己翻书,数据库原理。
select e.ename,d.dname from emp e,dept d;
表别名,增加可读性。
加条件,不会减少笛卡尔积匹配的数量,只不过是显示有效记录。
select e.ename,d.dname from emp e,detp d where e.deptno = d.deptno;
这个是SQL92的语法,以后不用。
2.3
内连接之等值连接:最大的特点是条件是等量关系。
案例:查询每个员工的部门名称,要求显示员工名和部门名。
SQL92:
select e.ename,d.dname from emp e,dept d where e.deptno = d.deptno;
SQL99:
select e.ename,d.dname from emp e join dept d on e.deptno = d.deptno;
语法:
...
A
inner join
B
on
连接条件
where
...
表连接的条件与where的条件分离了,这种语法结构更清晰。
inner 可以省略,代表着内连接,可读性更好。
2.4
内连接之非等值连接:连接条件中非等值的关系。
案例:找出每个员工的工资等级,要求显示员工名、工资、工资等级。
select
e.ename,e.sal,s.grade
from
emp e
inner join
salgrade s
on
e.sal between s.local and s.hissal;
2.7
自连接:自己连接自己
案例:找出每个员工的上级领导,要求显示员工名和对应的领导名。(领导也是员工,在同一个表中)
select
y.ename as '员工',l.ename as '领导'
from
emp y
inner join
emp l
on
y.mgr = b. empno;
这里是等量关系,当然也可以不使用等量关系。
2.8
外连接
与内连接的区别:内连接两表连接无主副之分。而2外连接需要规定主副表,主要查询主表中的数据,捎带着查询副表,如果副表中的数据没有和主表中的数据匹配上,副表自动模拟出null与之匹配。
两种分类:
左外连接:左边是主表
右外连接:右边是主表
左连接有右连接写法,右连接有左连接的写法。
案例:找出每个员工的上级领导。
select
a.ename '员工',b.ename '领导'
from
emp a
left join
emp b
on
a.mgr = b.empno;
加了个left,代表着左连接,以左边为主表,如果写right的话则就是右连接,以右边为主表。
2.9
全连接,两张表都是主表,都不能耽误两表查询。
2.10
三表连接。
···
A
join
B
on
···
join
C
on
···
案例:找出每一个员工的部门名称以及工资等级。
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 hisal;
案例:找出每个员工的部门名称以及工资等级还有他的领导。
3.子查询
select语句嵌套select语句
子查询可以出现在哪里?
select
···(select)
from
···(select)
where
···(select)
3.1
where后面嵌套子查询
案例:找出高于平均工资的员工信息。
select * from emp where sal >(select avg(sal) from emp);
3.2
from后面嵌套子查询
案例:找出每个部门平均薪水的薪水等级。
第一步:找出每个部门平均薪水(按照部门编号分组,求sal的平均值)
select deptno,avg(sal) as avgsal from emp group by deptno;
第二步:将以上的查询结果当做临时表t,让t表和salgrade s表连接:条件是:t.avgsal between s.losal and s.hisal。
select
t.*,s.grade
from
(select deptno,avg(sal) as avgsal from emp group by deptno) t
on
t.avgsal between s.losal and s.hisal;
3.3
在select后面嵌套子查询。
案例:找出每个员工所在的部门名称,要求显示员工和部门名。
这里利用select嵌套子查询。
select
e.ename,(select d.dname from dept d where e.deptno = d.deptno) as dname from emp e;
from
emp e;
3.4
union的用法
union(可以将查询结果相加)
案例:找出工作岗位是SALESMAN和MANAGER的员工?
这里使用union来查询。
select ename,job from emp where job = 'MANAGER'
union
select ename,job from emp where job = 'SALESMAN';
将两个查询的结果相加。
也可以两张不相干的两张表中的数据拼接在一起(虽然没有意义),但列数要一致。
3.5
limit的使用(分页查询)
是mysql中特有的,其它数据库没有,不通用。(Oracle中也有一个相同的机制)
作用:用来取结果集的部分数据。
案例:取出工资前五名。
select ename,sal from emp order by sal desc;
select ename,sal from emp order by sal desc limit 0,5;
limit 0,5取前五名,limit 5也一样。
limit 3,6取4到9名,这里6代表几个。
limit 的执行顺序是最后一个的。
select
...
from
...
where
...
group by
...
having
...
limit
...
数据库中大量的信息一次显示太多,需要分页显示。