一些简单的数据库题你看得懂不?

--select count(nvl(comm,0)) from emp;
--单出来一列
--select count(1) from emp;
--select AVG(sal) from emp;
--select SUM(sal+nvl(comm,0)) from emp;

select deptno,max(sal) from emp where deptno is not null group by deptno;       
select nvl(to_char(deptno),'临时部门'),max(sal) from emp group by deptno;    

聚合函数对一组值执行计算,并返回单个值。也叫组函数。

group by 子句的真正作用在于与各种聚合函数配合使用。它用来对查询出来的数据进行分组,分组后的数据执行组函数计算,最终结果自动按分组列进行 降 序 排列。

当查询中聚合列和非聚合列同时出现时,非聚合列必须出现在group by 之后


select nvl(to_char(deptno),'临时部门'),job,max(sal),count(1) from emp where job is not null group by deptno,job having (count(1)>1);

where 是在分组之前进行条件过滤,所以where子句中不能使用聚合函数
having 是在分组(group by)之后进行条件过滤,所以having可以使用聚合函数

1.2.2联接查询
多表连接查询
使用单个select 语句从多个表中取出相关的数据,通过多表之间的关系,构建相关数据的查询。
多表连接通常是建立在相互关系的父子表上的。
select ... from join_table JOIN_TYPE join_table ON join_condition where where_condition
join_table 参与连接的表 JOIN_TYPE 连接类型:内连接、外连接、交叉连接、自连接  join_condition 连接条件 where_condition where过滤条件


内连接语法:
select ... from join_table [INNER]JOIN join_table2 [ON join_condition] where where_definition

JOIN ON 是在8i之后版本才有的
只列出这些连接表中与连接条件相匹配的数据行。
内连接分类
等值连接:在连接条件中使用等号(=)运算符来比较被连接的列值
非等值连接:在连接条件中使用除等号运算符以外的其他比较运算符来比较被连接的列的列值
自然连接:在连接条件中使用等于(=)运算符来比较被连接列的列值,但它使用选择列表指出查询结果集合中所包括的列,并删除连接表中的重复列。
连接多个表时,尽量把中间表 写在第一个
--连接3个表    显示学生名 班级名 院系名
select tb1.name,tb2.classname,tb3.departname from student2 tn1 join class tb2 on tb1.classid=tb2.classid join department2 tb3 on tb1.departmentid=tb3.deptid

命令窗口下@c:/1.sql      @路径名.sql文件名 执行sql文件

--显示出所有员工的部门名称
select emp.ename,dept.dname from emp join dept on emp.deptno = dept.deptno;

--自然连接
select emp.ename,dept.dname from emp natural join dept;
--KING工作的部门啥叫名?
select emp.ename,dept.dname from emp join dept on emp.deptno=dept.deptno where emp.ename='KING';

--老方法 SQL92
select emp.ename,dept.dname from emp,dept where emp.deptno=dept.deptno and emp.ename='KING';
--显示10号部门的员工名和部门名
select emp.ename,emp.deptno,dept.dname from emp join dept on emp.deptno=dept.deptno where emp.deptno=10;

外连接语法
Select … from join_table (LEFT|RIGHT|FULL) [OUTER] JOIN join_table2 ON join_condition where where_condition

不仅列出与连接条件相匹配的行,还列出左表(左外连接)、右表(右外连接)或两个表(全外连接)中所有符合where过滤条件的数据行。
分类:
左外连接(LEFT[OUTER]JOIN)
右外连接(RIGHT[OUTER]JOIN)
全外连接(FULL[OUTER]JOIN)
--左外连接
Select dname,ename from dept tb1 left outer join emp on tb1.deptno=emp.deptno ;
--右外连接
select dname,ename from dept tb1 right outer join emp on tb1.deptno=emp.deptno ;
--全外连接    没什么实际意义
select dname,ename from dept tb1 full outer join emp on tb1.deptno=emp.deptno ;

--老方法 SQL92  +号  不突出显示的那一方加 +
select * from emp,dept where dept.deptno=emp.deptno(+);
交叉连接    没什么意义
Select … from join_table CROSS JOIN join_table2;
没有on子句和where子句,它返回连接表中所有数据行的笛卡尔积。   其结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数
相当于 select… from table1,table2;
自连接
参与查询的表都是头一张表
select t1.ename,t1.empno,t1.mgr,t2.ename 上级姓名 from emp t1 join emp t2 on t1.mgr=t2.empno;

子查询
某些情况下,当进行查询的时候,需要的条件是另外一个select语句的结果,这个时候,就要用到子查询。
为了给主查询(外部查询)提供数据而首先进行的查询(内部查询)被叫做子查询
用于子查询的关键字主要包括in,not in,=,<>等。
Exists ,not Exists  效率高点
--查月薪最高的员工的信息
select * from emp where sal=(select max(sal) from emp);
Oracle中的Null是一个不确定的状态
--查询出有员工的部门信息
select * from dept where deptno   in (select distinct(deptno) from emp);
select * from dept t1 where exists (select deptno from emp t2 where t1.deptno=t2.deptno);
--查询出没有员工的部门信息
select * from dept where deptno not  in (select distinct(nvl(deptno,0)) from emp)
--查询出每个部门的平均工资 部门名称
select dept.dname,t.部门平均工资  from dept join (select deptno,avg(nvl(sal,0)) 部门平均工资 from emp group by deptno) t on dept.deptno=t.deptno
--查询出平均工资最高的部门名称和编号
--显示部门名称和编号
--select t1.dname,t1.deptno from dept t1
--各个部门的平均工资
--select deptno,avg(sal) 平均工资 from emp group by deptno
--各个部门平均工资最高多少
--select max(temp.部门平均工资) from (select avg(sal) 部门平均工资 from emp group by deptno) temp;
select t1.dname,t1.deptno,temp1.平均工资 from dept t1 join (select deptno,avg(sal) 平均工资 from emp group by deptno having avg(sal)=( select max(temp.部门平均工资) from (select avg(sal) 部门平均工资 from emp group by deptno) temp)
) temp1 on t1.deptno=temp1.deptno ;
--使用with重用查询
--with不能越级,最后一个一定要使用,select 连同with一起执行
with 部门平均工资 as (select deptno 部门编号,avg(sal) 平均工资 from emp group by deptno)
select t.deptno, t.dname, 部门平均工资.平均工资 from dept t
  join 部门平均工资 on 部门平均工资.部门编号 = t.deptno join
(select max(平均工资) 最高工资 from 部门平均工资) 部门最高工资 on
部门平均工资.平均工资 = 部门最高工资.最高工资;
多行子查询
有些时候我们在使用子查询时,子查询可能会返回多行,这样就无法使用=,<>,>,<,>=,<=这样的运算符进行条件判断,我们又不想使用聚合函数(耗时)进行运算,这时我们可以使用多行子查询运算符 ANY SOME ALL
--比10部门中任意一个员工工资都高
select * from emp where sal>any(select sal from emp where deptno=10) and deptno<>10
SOME作用与ANY一样,只不过SOME通常应用于=运算
--比20部门中所有人工资都高
select ename,sal from emp where sal>all(select sal from emp where deptno=20)
关联子查询
子查询可以单独运行,不需要引用外层查询的任何结果,我们称为非关联子查询(以上我们写的都是非关联子查询)
反之就是关联子查询
--显示各个部门的人数     
select dname 部门名称,(select count(*) from emp  where emp.deptno=dept.deptno) 人数 from dept;

猜你喜欢

转载自cslichong.iteye.com/blog/1487353