zoukankan      html  css  js  c++  java
  • Oracle学习系列3

    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
    												
    												 ) ;
      
      */
    

     

  • 相关阅读:
    C# 实现 Snowflake算法生成唯一性Id
    kafka可视化客户端工具(Kafka Tool)的基本使用(转)
    docker 安装kafka
    Model类代码生成器
    使用docker 部署rabbitmq 镜像
    Vue 增删改查 demo
    git 提交代码到库
    Android ble蓝牙问题
    mac 配置 ssh 到git (Could not resolve hostname github.com, Failed to connect to github.com port 443 Operation timed out)
    okhttp
  • 原文地址:https://www.cnblogs.com/askDing/p/5467395.html
Copyright © 2011-2022 走看看