一、连接查询SQL99
1.1 交叉连接
作用:其效果等同于在两个表进行连接时未使用where子句限定连接条件;
SQL99:
select dept.deptno,dname,ename from dept cross join emp;
SQL92:
select dept.deptno,dname,ename from dept,emp;
运行结果:
1.2 自然连接
Natural join:基于两个表中的全部同名列建立连接,从两个表中选出同名列的值均对应相等的所有行
注1:如果两个表中同名列的数据类型不同,则出错
注2:不允许在参照列上使用表名或者别名作为前缀
注3:自然连接的结果不保留重复的属性
举例:
select empno, ename, sal, deptno, dname from emp natural join dept
运行结果:
1.3 Using 子句
如果不希望参照被连接表的所有同名列进行等值连接,自然连接将无法满足要求,可以在连接时使用USING子句来设置用于等值连接的列(参照列)名。
using子句引用的列在sql任何地方不能使用表名或者别名做前缀
select e.ename,e.ename,e.sal,deptno,d. dname
from emp e join dept d
using(deptno)
where deptno=101
1.4 On子句
自然连接的条件是基于表中所有同名列的等值连接。为了设置任意的连接条件或者指定连接的列,需要使用ON子句。连接条件与其它的查询条件分开书写,使用ON 子句使查询语句更容易理解
实例:
select ename,dname from emp inner join dept
on emp.deptno=dept.deptno
where emp.deptno=30;
运行结果:
实例:
select empno, ename, sal, emp.deptno, dname from emp inner join dept
on (emp.deptno = dept.deptno and sal>1000);
运行结果:
实例:
select * from dept, emp where dept.deptno = emp.deptno and sal>1000;
运行结果:
1.5 外连接
左外连接:
两个表在连接过程中除返回满足连接条件的行以外,还返回左表中不满足条件的行,这种连接称为左外联接。
select * from 表1 别名1 left [outer] join 表2 别名2 on 别名1.xx=别名2.xx
select * from emp e left outer join dept d on e.deptno=d.deptno;
select e.ename,e.deptno,d.dname from emp e left
outer join dept d on e.deptno=d.deptno;
右外连接:
两个表在连接过程中除返回满足连接条件的行以外,还返回右表中不满足条件的行,这种连接称为右外联接。
select * from 表1 别名1 right [outer] join 表2 别名2 on 别名1.xx=别名2.xx
select * from emp e right outer join dept d on e.deptno=d.deptno;
二、子查询
1)单行子查询
举例:查询工资比CLEARK高的所有人的工资
select * from emp
where sal>(select sal from emp where ename='CLARK');
举例:查询职务和SCOTT相同,比SCOTT雇佣时间早的雇员信息
SELECT empno, ename, job FROM emp
WHERE job =(SELECT job FROM emp WHERE empno=7788)
AND hiredate < (SELECT hiredate FROM emp WHERE empno=7788);
举例:查询工资比SCOTT高or雇佣时间比SCOTT早的雇员的编号和名字
select empno,ename,sal,hiredate
from emp
where sal>(select sal from emp where ename='SCOTT')
or hiredate<(select hiredate from emp where ename='SCOTT')
2)多行子查询
all:和子查询返回的所有值比较
any:和子查询返回的任意一个值比较
in:等于列表中的任何一个
举例:查询工资低于任何一个'CLERK'的工资的雇员信息。
SELECT empno, ename, job,sal
FROM emp
WHERE sal < ANY (SELECT sal FROM emp WHERE job = 'CLERK') AND job <> 'CLERK';
运行结果:
举例:查询工资比所有的 'SALESMAN'都高的雇员的编号、名字和工资。
SELECT empno, ename,sal
FROM emp
WHERE sal > ALL(SELECT sal FROM emp WHERE job= 'SALESMAN');
运行结果:
举例:查询部门20中职务同部门10的雇员一样的雇员信息。
SELECT empno, ename, job FROM emp
WHERE job IN (SELECT job FROM emp WHERE deptno=10)
AND deptno =20;
运行结果:
举例:查询工资不是最高也不是最低的员工工资
select * from emp where sal !=(select max(sal) from emp ) and sal !=
(select min(sal) from emp);
举例:不是销售员的员工信息
--法一:
select * from emp where deptno != (select deptno from dept where
dname='sales');
--法二:
select * from emp where deptno in(select deptno from dept where
dname !='sales');
举例:查询员⼯信息,要求⼯资⾼于部⻔编号为10的中的任意员⼯即可
--法一:
select * from emp where sal >(select min(sal) from emp where
deptno=10);
--法二:
select * from emp where sal >any (select sal from emp where
deptno=10);
举例:查询每个部门的平均薪水
select * from
salgrade s, (select deptno,avg(sal) avg_sal
from emp group by deptno) t
where t.avg_sal between s.losal and s.hisal;
运行结果: