1、连接
用一个连接来从多个表中获取数据。
select table.column,table2.column
from table1,table2
where table1.column1=table2.column2;
在where子句中书写连接的条件。
如果某个列的名字在多个表中出现了,
那么需要在列的名字前加上表名作为前缀。
·内连接
舍弃不匹配的元组
select * from emp inner join dept on emp.deptno = dept.deptno;
·自然连接
合并相同字段的列
select * from emp natural join dept;
·左外连接
内连接+左边关系中失配的元组(缺少的右边关系属性值用null表示)
//左边的表每项保留,右边用null补齐
select * from emp left outer join dept on emp.deptno = dept.deptno;
·右外连接
内连接+右边关系中失配的元组(缺少的左边关系属性值用null表示)
//右边的表每项保留,左边用null补齐
select * from emp e,dept d where e.deptno (+)= d.deptno;
·全连接
内连接+左边关系中失配的元组(缺少的右边关系属性值用null表示)
+右边关系中失配的元组(缺少的左边关系属性用null表示)
select * from emp full outer join dept on emp.deptno = dept.deptno;
·cross join
两个关系的笛卡尔积。//严禁使用
注意:在三个以上数量的表连接时不要忘记各个表的连接条件
否则会产生笛卡尔积。
2、笛卡尔积
以笛卡尔积连接的表具有下列特征:
·连接条件被忽略;
·第一个表的所有的行与第二个表中的所有行相连接。
如果在where子句中条件,那么可以避免笛卡尔积
3、表的别名
select ename,e.deptno,d.loc from emp e,dept d where e.deptno=d.deptno;
//在from后面写表名时用空格隔开别名,语句中其他位置必须使用别名
#############################练习#######################################
##单表查询
1、查询emp表中的所有信息
select * from emp;
2、显示emp表中的员工姓名和工资
select ename,sal from emp;
3、查询emp表中部门编号为20的并且sal(工资)大于3000的所有员工信息
select * from emp where deptno = 20 and sal > 3000;
4、查询emp表中部门编号为20的或者sal(工资)大于3000的所有员工信息
select * from emp where deptno = 20 or sal > 3000;
5、使用between and查询工资在2000和4000之间的员工(用and重新实现)
select * from emp where sal between 2000 and 4000;
6、使用in 查询部门编号10,20的所有员工
select * from emp where deptno in (10,20);
7、使用like查询所有名字中包括W的员工信息
select * from emp where ename like '%W%';
8、使用like查询所有员工名字中第二个字母为W的员工信息
select * from emp where ename like '_W%';
9、查询所有员工信息并按照部门编号和工资进行排序
select * from emp order by deptno,sal asc;
10、显示员工工资上浮20%的结果。
select ename,sal,(emp.sal*1.2)as increase_sal from emp;
11、显示emp表的员工姓名以及工资和奖金的和
select ename,sal+nvl(comm,0) as total_sal from emp;
12、显示dept表的内容,使用别名将表头转换成中文显示
select deptno 部门编号,dname 部门名字,loc 地点 from dept;
13、查询员工姓名和工资,并按雇用日期排序,后雇用的先显示
select ename 员工姓名,sal 工资 from emp order by hiredate desc;
14、查询员工信息,先按部门标号从小到大排序,再按雇用时间的先后排序
select * from emp order by deptno,hiredate asc;
########################多表查询###########################################
1、列出在部门sales工作的员工的姓名
select emp.ename
from emp, dept
where emp.deptno = dept.deptno
and dept.dname = 'SALES';
2、列出所有员工的姓名,部门名称和工资
select emp.ename, dept.dname, emp.sal
from emp, dept
where emp.deptno = dept.deptno;
3、列出所有部门的详细信息和部门人数
select dept.*, count(ename)
from emp, dept
where emp.deptno(+) = dept.deptno
group by dept.deptno, dname, loc;
4、列出各个部门职位为manager的最低薪金
select dept.dname, min(emp.sal)
from emp, dept
where emp.deptno = dept.deptno and job ='MANAGER'
group by dept.dname;
5、查询出部门人数至少为1的部门名字
select distinct dept.dname
from emp, dept
where emp.deptno = dept.deptno
group by dept.dname
having count(ename) >= 1;
6、列出工资比Smith多的员工
select ename
from emp
where ename != 'SMITH'
and sal > (select sal from emp where ename = 'SMITH');
7、列出所有员工的对应领导的姓名
select e1.ename, e2.ename
from emp e1
left join emp e2 on e1.mgr = e2.empno;
8、求出某个员工的领导,并要求这些领导的薪水高于或等于3000
select distinct e2.ename
from emp e1
left join emp e2 on e1.mgr = e2.empno
where e2.sal >= 3000;
9、列出部门名称,和这些部门的员工信息
select dept.dname,
dept.deptno,
emp.empno,
emp.ename,
emp.job,
emp.mgr,
emp.hiredate,
emp.sal,
emp.comm
from emp
right join dept on emp.deptno = dept.deptno;
10、列出所有职位为clerk的员工姓名及其部门名称,部门的人数
--子查询部门名称,人数
select dept.deptno, dname, count(ename)
from emp
right join dept on emp.deptno = dept.deptno
group by dept.deptno,dname order by dept.deptno;
select emp.ename, a.dname, a.人数
from emp
left join (select dept.deptno, dname, count(ename) 人数
from emp
right join dept on emp.deptno = dept.deptno
group by dept.deptno, dname) a on emp.deptno = a.deptno
where emp.job = 'CLERK';
11、列出薪金高于公司平均薪金的所有员工,所在部门,上级领导,公司的工资等级
select e.ename, d.dname, l.ename 上级领导, s.grade
from emp e, emp l, dept d, salgrade s
where e.deptno = d.deptno
and e.mgr = l.empno(+)
and e.sal > (select avg(sal) from emp)
and e.sal between s.losal and s.hisal;
12、列出与scott从事相同工作的所有员工及其部门名称
select ename, dname
from emp, dept
where emp.deptno = dept.deptno
and job = (select job from emp where ename = 'SCOTT')
and ename != 'SCOTT';
13、列出薪金大于部门30中的任意员工的薪金的所有员工的姓名和薪金
select ename, sal
from emp
where sal > any (select sal from emp where deptno = 30);
14、列出薪金大于部门30中全部员工的薪金的所有员工的姓名和薪金,部门名称
select ename, sal, dname
from emp, dept
where emp.deptno = dept.deptno
and sal > all (select sal from emp where deptno = 30);
15、列出每个部门的员工数量,平均工资
select dept.deptno,dept.dname, count(*), avg(sal)
from emp, dept
where emp.deptno = dept.deptno
group by dept.deptno,dept.dname
order by dept.deptno;
16、列出每个部门的员工数量,平均工资和平均服务期限(月)
select deptno,
count(*) 员工数量,
trunc(avg(sal + nvl(comm, 0))) 平均工资,
trunc(avg(sysdate - hiredate) / 30) 平均服务期限
from emp
group by deptno;
17、列出各种工作的最低工资及从事工资最低工作的雇员名称
select ename
from emp
where (job, sal) in (select job, min(sal) from emp group by job);
18、求出部门名称带字符'S'的部门员工,工资合计,部门人数
select dept.deptno,
dept.dname 部门名称,
sum(sal + nvl(comm, 0)) 工资合计,
count(ename) 部门人数
from emp, dept
where emp.deptno(+) = dept.deptno
and dname like '%S%'
group by dept.deptno, dname;
19、求出部门平均工资以及等级
select a.deptno, a.平均工资, s.grade
from (select deptno, trunc(avg(sal)) 平均工资 from emp group by deptno) a,
salgrade s where 平均工资 between s.losal and s.hisal;
20、不使用函数查询工资最高人的信息
----------(1)
select * from emp where sal >= all (select sal from emp);
----------(2)
select * from (select * from emp order by sal desc) where rownum = 1;
21、求出平均工资最高的部门名称
-----(1)
with deptavgsal as(
select dname, trunc(avg(sal + nvl(comm, 0))) 平均工资
from emp, dept
where emp.deptno = dept.deptno
group by dname)
select dname
from deptavgsal
where 平均工资 = (select max(平均工资) from deptavgsal);
-----(2)
select dname
from (select dname
from emp, dept
where dept.deptno = emp.deptno
group by dname
order by avg(sal + nvl(comm, 0)) desc)
where rownum = 1;
22、求平均工资的等级最低的部门名称
------(1)
select dname
from (select dname, grade
from (select dname, avg(sal + nvl(comm, 0)) 平均工资
from emp, dept
where emp.deptno = dept.deptno
group by dname
order by avg(sal + nvl(comm, 0))),
salgrade
where 平均工资 between losal and hisal
order by grade)
where rownum = 1;
------(2)
select a.dname 部门名称, grade
from (select dname, trunc(avg(sal + nvl(comm, 0))) 平均工资
from emp, dept
where emp.deptno = dept.deptno
group by dname) a,
salgrade
where 平均工资 between losal and hisal
and grade =
(select min(grade)
from (select b.dname 部门名称, grade
from (select dname, trunc(avg(sal + nvl(comm, 0))) 平均工资
from emp, dept
where emp.deptno = dept.deptno
group by dname) b,
salgrade
where 平均工资 between losal and hisal));
------(3)
with deptavgsal as(
select dname, trunc(avg(sal + nvl(comm, 0))) 平均工资
from emp, dept
where emp.deptno = dept.deptno
group by dname)
select dname 部门名称, grade
from deptavgsal, salgrade
where 平均工资 between losal and hisal
and grade = (select min(grade)
from (select dname 部门名称, grade
from deptavgsal, salgrade
where 平均工资 between losal and hisal));
23、部门经理人中平均工资最低的部门名称
-------(1)
select dname
from (select dname, avg(工资)
from (select distinct l.ename,
l.deptno 部门编号,
l.sal + nvl(l.comm, 0) 工资
from emp e, emp l
where e.mgr = l.empno) m,
dept
where m.部门编号 = dept.deptno
group by dname
order by avg(工资))
where rownum = 1;
--------(2)
with mgravgsal as(
select 部门名称, trunc(avg(工资)) 平均工资
from (select distinct l.ename 领导,
d.dname 部门名称,
l.sal + nvl(l.comm, 0) 工资
from emp e, emp l, dept d
where e.mgr = l.empno
and l.deptno = d.deptno)
group by 部门名称)
select 部门名称
from mgravgsal
where 平均工资 = (select min(平均工资) from mgravgsal);