Oracle学习系列3
************************************************************************************
多表查询:
		1,SQL1999语法对多表查询的支持
		2,分组统计及统计函数的使用
		3,子查询,并结合多表查询,分组统计做复杂查询
		4,数据库的更新操作
		5,事务处理和数据库死锁

************************************************************************************
多表查询:
	语法:
		select { distinct } * | col1 别名1   col2 别名2 ...
			from  tab1 别名1 , tab2 别名2 , tab3 别名3 ,...
				{where 条件s }
					{ order by col1 ASC | DESC , col2  ASC | DESC, ...} ;

	同时查询emp表和dept表:
		select *
			from emp, dept ;   //产生笛卡尔积

		加入where语句:
			select *
				from emp  e,dept  d
					where e.deptno = d.deptno;

	要求查询出雇员的编号,姓名,部门编号,部门名称,部门位置:
			select e.empno, e.ename, d.deptno, d.dname, d.loc
				from emp e, dept d
					where e.deptno=d.deptno;

	要求查询出每个雇员的姓名,工作,雇员的直接上级领导的姓名:
			select e.ename, e.job, m.ename, d.dname
				from emp e, emp m ,dept d
					where e.mgr = m.empno and e.deptno=d.deptno ;

	要求查询出每个雇员的姓名,工资,部门名称,工资在公司的等级,及其领导的姓名及工资所在公司的等级:
		select e.ename, e.sal, d.dname, s.grade, m.ename, m.sal, ms.grade
			from emp e, dept d, salgrade s, emp m, salgrade ms
				where e.deptno=d.deptno and (e.sal between s.losal and s.hisal)
						and e.mgr=m.empno     and ( m.sal between ms.losal and ms.hisal);

			进一步:按照下面样式显示工资等级:
				1:第五等工资
				2:第四等工资
				3:第三等工资
				4:第二等工资
				5:第一等工资
				此时肯定使用decode()函数:

				select e.ename, e.sal, d.dname, DECODE(s.grade, 1,'第五等工资',2,'第四等工资',3,'第三等工资',4,'第二等工资',1,'第一等工资'),
						 m.ename,m.sal,DECODE(ms.grade, 1,'第五等工资',2,'第四等工资',3,'第三等工资',4,'第二等工资',1,'第一等工资'),
					from emp e, dept d, salgrade s, emp m, salgrade ms
								where e.deptno=d.deptno and (e.sal between s.losal and s.hisal)
											and e.mgr=m.empno
										  and ( m.sal between ms.losal and ms.hisal);

************************************************************************************

	左、右连接<重点>

	(+)=    -->右连接,
	 =(+)   -->左连接,  默认

		select e.empno, e.ename, d.deptno, d.dname, d.loc
			from emp e, dept d
				where e.deptno(+)=d.deptno; //表示以dept表为准  。右连接

************************************************************************************

SQL:1999语法对SQL的支持<了解>

	交叉连接(cross join):  <产生笛卡尔积>
		select * from emp corss join dept ;

	自然连接(natural join):<自动进行关联字段的匹配>
		select * from emp natural join dept ;

	USING子句:<直接指定关联的操作列>
		select *
			from emp e join dept d USING(deptno)
				where deptno=30;

	ON子句:<用户自定义连接条件>
		select *
			from emp e join dept d  ON(e.deptno=d.deptno)
				where e.deptno=30 ;

	左连接(left join),右连接(right join):
		select e.ename, d.deptno, d.dname, d.loc
			from emp e right outer join dept d
				on(e.deptno=d.deptno) ;

************************************************************************************
组函数和分组统计:<重点>

	count(): 	//求出全部记录数
	max():		//	求出一组中最大值
	min():		//最小值
	avg(): 		//平均值
	sum():      //求和

		count()函数:
			select count(emp) from emp ;  //查询多少行记录

		max(),min()函数:求出所有员工的最低工资
			select max(sal) ,min(sal) , sum(sal) from emp ;

分组统计<group by>:

		语法:
		select { distinct } * | col1 别名1   col2 别名2 ...
			from  tab1 别名1 , tab2 别名2 , tab3 别名3 ,...
				{where 条件s }
					{group by 分组条件}
						{ order by col1 ASC | DESC , col2  ASC | DESC, ...} ;

		求出每个部门的雇员数量,可定按照部门编号划分:
			select deptno, count(empno)
				from emp
					group by deptno ;

		求出每个部门的平均工资:
			select deptno, avg(sal)
				from emp
					group by deptno ;
---------------------------------------------------------------------------------
		select deptno, count(empno) from emp ;// error:不是单组分组函数
		/**
			若程序使用了分组函数,条件如下;
				1.程序中存在group by ,并且指定了分组条件,这样可以将分组条件一起查询出来
				2.若不用分组的话,则只能单独使用分组函数
				3.在使用分组函数时,不能出现分组函数和分组条件(group by )之外的字段
						|
		  */		    |
		  				|
						^
				select deptno ,empno, count(empno)	  //error:empno不是group by 的表达式
					from emp
						group by deptno ;

		按部门分组,并显示部门的名称,及每个部门的员工数:
			select d.dname, count(e.empno)
				from dept d, emp e
					where d.deptno = e.deptno
						group by d.dname ;

		要求显示出平均工资大于2000的部门编号和平均工资:
			 error:	select deptno , avg(sal)
			 			from emp
							where avg(sal) >2000    //此处不允许使用分组函数
								group by deptno ;
  /**
  	分组函数只能在分组中使用,不允许出现在where语句中,若现在假设要指定分组条件,则只能通过第二种指令:having,此时SQL语法格式:

			select { distinct } * | col1 别名1   col2 别名2 ...
				from  tab1 别名1 , tab2 别名2 , tab3 别名3 ,...
					{where 条件s }
						{group by 分组条件   { having  分组条件 }  }
							{ order by col1 ASC | DESC , col2  ASC | DESC, ...} ;

	*/

			correct: select deptno, avg(sal)
						from emp
							group by deptno  having avg(sal)>2000 ;

		显示非销售人员工作名称以及从事统一工作雇员的月工资的总和,并且满足从事同一工作的雇员的月工资合计大于$5000,输出结果按月工资的合计升序排列:

		/**

			分组简单的原则:
				1,只要一列上存在重复的内容才有可能考虑到分组
				2,分组函数可以嵌套使用,但是嵌套使用时不能再出现group by 后的字段:
					ex:求出平均工资最高的部门:
						error:	 select  deptno, max(avg(sal))  //不是单组分组函数
									from emp
										group by deptno;

						correct: select max(avg(sal))
									from emp
										group by deptno ;
		--------------------------------------------------------------------------------
			分析:1,显示全部非销售人员:job<> 'salesman'

					select * from emp  where job <>'salesman' ;

				2,按工作分组,同时求出工资的总和:

					select job,sum(sal)
						from emp
							where job<> 'salesman'
								group by job ;

				3,对分组条件进行限制,工资总和大于500:
					select job,sum(sal)
						from emp
							where job<> 'salesman'
								group by job having sum(sal)>5000 ;		

				4,按升序排序:
					select job,sum(sal) su
						from emp
							where job<> 'salesman'
								group by job having sum(sal)>5000
									order by su ;
		 */

************************************************************************************

子查询:
	在一个查询内部还可以包括另一个查询:

	分类:
		单列子查询:返回的结果是一列的一个内容 (出现几率最高)
		单行子查询:返回多个列,有可能为一条完整的记录
		多行子查询:返回多个记录

	格式:
		select { distinct } * | col1 别名1   col2 别名2 ...
			from  tab1 别名1 , tab2 别名2 ,
				(
						select { distinct } * | col1 别名1   col2 别名2 ...
							from  tab1 别名1 , tab2 别名2 , tab3 别名3 ,...
								{where 条件s }
									{group by 分组条件   { having  分组条件 }  }
										{ order by col1 ASC | DESC , col2  ASC | DESC, ...} ;

					 )别名x 	tab3 别名3 ,...
					{where 条件s
						(
						select { distinct } * | col1 别名1   col2 别名2 ...
							from  tab1 别名1 , tab2 别名2 , tab3 别名3 ,...
								{where 条件s }
									{group by 分组条件   { having  分组条件 }  }
										{ order by col1 ASC | DESC , col2  ASC | DESC, ...} ;

					 )

					}
						{group by 分组条件   { having  分组条件 }  }
							{ order by col1 ASC | DESC , col2  ASC | DESC, ...} ;

   要求查询出比7654工资高的全部雇员的信息:
   		分析:
			1,7654雇员的工资是多少:
				select sal from emp where empno=7654 ;

			2,只要是其他工资大于7654编号雇员的工资,则符合条件:
				select *
					from emp
						where sal > (

							select sal from emp where empno=7654;  //子查询语句处

							)		;

	要求查询出工资比7654高,同时与7788从事相同工作的全部雇员信息:
		查询出7654雇员的工资:
			select sal from emp where empno=7654 ;

		与7788从事相同的工作:
			select job from emp
				where empno = 7788;

		综合查找:
			select *
				from emp
					where sal >(

							select sal from emp where empno=7654 

						)and  job =(
								select job from emp where empno =7788

						     ) ;

	要求查询出工资最低雇员姓名,工作,工资:
		最低工资:
			select min(sal) from emp ;

		查询所有:
			select *
				from emp
					where sal =(

						select min(sal) from emp 

						) ;

		要求查询:部门名称,部门员工数,部门的平均工资,部门的最低收入的雇员的姓名:

			1,求出每个部门的员工数量,平均工资
				select deptno,count(empno) ,avg(sal)
					from emp
						group by  deptno ;

			2,查出部门的名称:
				select d.dname, ed.c, ed.a
					from dept d, (
						select deptno,count(empno) ,avg(sal)
							from emp
								group by  deptno
					     ) ed
						where d.deptno=ed.deptno ;
			3,求出最低收入的雇员姓名:
				select d.dname, ed.c, ed.a  ,e.ename
					from dept d, (
						select deptno,count(empno) ,avg(sal),min(sal) min							from emp
								group by  deptno
					     ) ed ,emp e
						where d.deptno=ed.deptno
								and e.sal =ed.min ;
					//若一个部门中存在两个最低工资的雇员,则该脚本会出现错误

          ------------------------------------------------------

子查询中的三种操作符:

				IN, ANY, ALL
		求出每个部门的最低工资的雇员信息:
			select *
			from emp
				where sal IN (  //指定查询范围

						select min(sal)
							from emp
					         	group by deptno	

						) ;

		=ANY : 与IN功能一样
			select *
			from emp
				where sal =ANY (  //指定查询范围

						select min(sal)
							from emp
					         	group by deptno	

						) ;

		>ANY:比里面最小的值要大
			select *
			from emp
				where sal >ANY (  //指定查询范围

						select min(sal)
							from emp
					         	group by deptno	

						) ;

		<ANY :比里面最大的值要小
			select *
			from emp
				where sal <ANY (  //指定查询范围

						select min(sal)
							from emp
					         	group by deptno	

						) ;

		==========================
		>ALL:比最大的值要大

		 	select *
			from emp
				where sal >ALL (  //指定查询范围

						select min(sal)
							from emp
					         	group by deptno	

						) ;

		<ALL:比最大的值要小
			select *
			from emp
				where sal <ALL (  //指定查询范围

						select min(sal)
							from emp
					         	group by deptno	

						) ;

  /**
  		对于子查询中,还可以进行多列子查询,一个子查询中同时返回多个查询的列
  				select  *
					from emp
						where (sal, NVL(comm,-1)) IN(

											select sa,NVL(comm, -1)
												from emp
													where deptno=20

												 ) ;

  */

Oracle学习系列3的更多相关文章

  1. Oracle学习系列1-7

    Oracle学习系列1 两个服务必须启动: OracleOraDb10g*TNListener 和 OracleService*** 使用sqlplusw先进行环境的设置 set linesize 3 ...

  2. Oracle学习系列7

    Oracle学习系列7 ************************************************************************************ 关联表 ...

  3. Oracle学习系列6

    Oracle学习系列6 ************************************************************************************ 删除约 ...

  4. Oracle学习系列5

    Oracle学习系列5 ************************************************************************************ ,掌握 ...

  5. Oracle学习系列4

    Oracle学习系列4 ************************************************************************************ 数据库 ...

  6. Oracle学习系列1

    两个服务必须启动: OracleOraDb10g*TNListener 和 OracleService*** 使用sqlplusw先进行环境的设置 set linesize 300 ; set pag ...

  7. oracle学习系列之四 (视图)

    视图视图是数据库中特有的对象.视图用于存储查询,但不会存储数据(物化视图除外).这是视图和数据表的重要区别.可以利用视图进行查询,插入,更新和删除数据.Oracle有如下四种视图(关系视图,内嵌视图, ...

  8. oracle学习系列之三 (约束)

    主键约束:外键约束:唯一性约束:检查约束:默认值约束 -——————五大约束 一. 主键约束: --创建表的主键约束  create table student (student_id number ...

  9. Oracle 学习系列之二(会话与事务级临时表和dual表 )

    一. 会话临时表 --创建会话临时表create global temporary table tmp_user_session(user_id int, user_name varchar2(20) ...

随机推荐

  1. Oracle常用的函数

    1.常用的函数分为五大类: 字符函数.数字和日期函数.数字函数.转换函数.混合函数 2.字符函数 字符函数主要用于修改字符列.这些函数接受字符输入,返回字符或数字值.Oracle 提供的一些字符函数如 ...

  2. 支持.NET和移动设备的XLS读写控件XLSReadWriteII下载地址及介绍

    原文来自龙博方案网http://www.fanganwang.com/product/3085转载请注明出处 读写任何单元值 数字型.字符型.布尔型以及错误型.但是你了解日期和时间型单元吗?在Exce ...

  3. 理解Objective C 中id

    什么是id,与void *的区别 id在Objective C中是一个类型,一个complier所认可的Objective C类型,跟void *是不一样的,比如一个 id userName, 和vo ...

  4. HDU 3336 - Count the string(KMP+递推)

    题意:给一个字符串,问该字符串的所有前缀与该字符串的匹配数目总和是多少. 此题要用KMP的next和DP来做. next[i]的含义是当第i个字符失配时,匹配指针应该回溯到的字符位置. 下标从0开始. ...

  5. linux命令:rmdir

    1.命令介绍: rmdir只能用来删除空目录,删除某目录时必须对其父目录有读权限. 2.命令选项: rmdir [选项] 目录 3.命令参数: -p --parent 递归删除目录dirname,当子 ...

  6. Win7 登入提示临时漫游档案

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList

  7. Hello WPF!

    WPF是微软提供的用户界面框架,它提供了统一的编程模型.语言,实现了分离界面设计人员与开发人员的工作.相对基于C++的MFC来说,界面更加美观,操作更加便捷,是新WIN环境下UI的首选. vs中新建W ...

  8. asp.net ToString()格式汇总

    C 货币 2.5.ToString("C") ¥2.50 D 十进制数 25.ToString("D5") 00025 E 科学型 25000.ToString ...

  9. wireshark使用详解

    编号:1009时间:2016年4月29日15:52:44功能:wireshark使用详解URl:http://blog.jobbole.com/70907/URL:http://www.9upk.co ...

  10. Visual Studio 2010 单元测试

    转载出处:http://blog.csdn.net/tjvictor/article/details/6175362