oracle_day2

第三章:单值函数
函数分为:
1.单值函数
1.字符函数
2.日期函数
3.转换函数
4.数字函数
2.分组函数

哑表dual
  dual是一个虚拟表,用来构成select的语法规则,oracle保证dual里面永远只有一条记录。
  例如:
  显示1+1的结果,可以看出,dual很多时候是为了构成select的标准语法
  select 1+1 from dual;

0
字符函数
  LOWER		Converts to lowercase
  UPPER		Converts to uppercase
  INITCAP	Converts to initial capitalization
  CONCAT	Concatenates values
  SUBSTR	Returns substring
  LENGTH	Returns number of characters
  NVL		Converts a null value	

  lower 把字符转为小写
	  例如:把'HELLO'转换为小写
	  select lower('HELLO')
	  from dual;
	  
	  例如:把s_emp表中的last_name列的值转换为小写
	  select lower(last_name)
	  from s_emp;
	
  upper 把字符转换为大写
	  例如:把'world'转换为大写
	  select upper('world')
	  from dual;

	  例如:把s_emp表中的last_name列的值转换为大写
	  select upper(last_name)
	  from s_emp;
      
	  
	  例如:查询s_emp表中名字为Ngao的人信息
	  这样是查不到:
	  select last_name,salary,dept_id
	  from s_emp
	  where last_name='NGAO';
      这样就可以查询到了:
	  select last_name,salary,dept_id
	  from s_emp
	  where upper(last_name)='NGAO';

  initcap 把字符串首字母转换为大写
	  例如:把'hELLO'转换为首字母大写,其余字母小写
	  select initcap('hELLO')
	  from dual;

  
  concat 把俩个字符串连接在一起(类似之前的||的作用)
	  例如:把'hello'和'world'俩个字符串连接到一起,并且起个别名为msg
	  select concat('hello','world') msg
      from dual;
	  
	  例如:把first_name和last_name俩个列的值连接到一起
	  select concat(first_name,last_name) as na
      from s_emp
	  where na not like '%S%';

  
  substr 截取字符串
	  例如:截取'hello'字符串,从第2个字符开始(包含第二个字符),截取后面连续的3个字符
	  select substr('hello',2,3)
	  from dual;


  length 获得字符串长度
	  例如:获得'world'字符串的长度
	  select length('world')
	  from dual;

	  例如:获得s_emp表中last_name列的每个值的字符长度
	  select length(last_name)
	  from s_emp;

  nvl 替换列中为null的值
	  在前面的章节已经使用过了
	  select last_name,nvl(commission_pct,0)
	  from s_emp;

数字函数
  ROUND		Rounds value to specified decimal
  TRUNC		Truncates value to specified decimal
  MOD		Returns remainder of division   


  round 四舍五入
	  round(arg1,arg2)
	  第一个参数表示要进行四舍五入操作的数字
	  第二个参数表示保留到哪一位

	  例如:
	  保留到小数点后面2位
	  select round(45.923,2)
	  from dual;

	  保留到个位 (个十百千万...)
	  select round(45.923,0)
	  from dual;

	  保留到十位 (个十百千万...)
	  select round(45.923,-1)
	  from dual;


  trunc 截取到某一位 
	  trunc(arg1,arg2)
	  和round的用法一样,但是trunc只舍去不进位

	  例如:
	  截取到小数点后面2位
	  select trunc(45.929,2)
	  from dual;

	  截取到个位 (个十百千万...)
	  select trunc(45.923,0)
	  from dual;

	  截取到十位 (个十百千万...)
	  select trunc(45.923,-1)
	  from dual;			


  mod 取余
	  mod(arg1,arg2)	
	  第一个参数表示要进行取余操作的数字
	  第二个参数表示参数1和谁取余
	  
	  例如:
	  把10和3进行取余 (10除以3然后获取余数)
	  select mod(10,3)
	  from dual;



日期函数
  MONTHS_BETWEEN   Number of months between two dates
  ADD_MONTHS	   Add calendar months to date
  NEXT_DAY		   Next day of the date specified
  LAST_DAY	       Last day of the month
  ROUND	           Round to date at midnight
  TRUNC	           Remove time portion  from date


  sysdate关键字
	表示系统的当前时间	
	例如:
	显示时间:当前时间
	select sysdate from dual;

	注意:sysdate进行加减操作的时候,单位是天
	例如:
	显示时间:明天的这个时候
	select sysdate+1 from dual;

	例如:
	显示时间:昨天的这个时候
	select sysdate-1 from dual;
	
	例如:
	显示时间:1小时之后的这个日期
	select sysdate+1/24 from dual;

	
  months_between 俩个日期之间相差多少个月(单位是月)
	例如:
	30天之后和现在相差多少个月
	select months_between(sysdate+30,sysdate)
	from dual;


  add_months  返回一个日期数据:表示一个时间点,往后推x月的日期
	例如:
	'01-2月-2019'往后推2个月
	select add_months('01-2月-2019',2)
	from dual;	
	
	例如:
	当前时间往后推4个月
	select add_months(sysdate,4)
    from dual;

	注意:这个数字也可以是负数,表示往前推x月

  next_day 返回一个日期数据:表示一个时间点后的下一个星期几在哪一天
	例如:
	离当前时间最近的下一个星期5是哪一个天
	select next_day(sysdate,'星期五')
	from dual;
	注意:
	如果要使用'FRIDAY',那么需要把当前会话的语言环境修改为英文
	alter session set nls_language=english;
	alter session set nls_language='simplified chinese';


  last_day 返回一个日期数据:表示一个日期所在月份的最后一天
	例如:
	当前日期所在月份的最后一天(月底)
	select last_day(sysdate)
	from dual;


  round  对日期进四舍五入,返回操作后的日期数据
	例如:
	把当前日期四舍五入到月
	select round(sysdate,'MONTH')
	from dual;
	测试:15号16号分别是舍弃还是进位
	
	把当前日期四舍五入到年
	select round(sysdate,'YEAR')
	from dual;
	
	//这个写法是错误的
	//数字函数也有一个round
	//俩个ronnd函数有冲突
	//所以这里不能使用默认的日期格式
	select round(to_date('01-02-2019'),'MONTH')
	from dual;

  trunc  对日期进行截取 和round类似,但是只舍弃不进位




类型转换函数
  TO_CHAR converts a number or date string to a character string.

 TO_NUMBER converts a character string containing digits to a number.
 TO_DATE converts a character string of a date to a date value.

  to_char 把日期转换为字符

    例如:
	把当前日期按照指定格式转换为字符串
	select to_char(sysdate,'yyyy')
	from dual;
	
	  日期格式:
	  yyyy:四位数的年份
	  rrrr:四位数的年份
	  yy:两位数的年份
	  rr:两位数的年份
	  mm:两位数的月份(数字)
	  D:一周的星期几
	  DD:一月的第几天
	  DDD :一年的第几天
	  YEAR:英文的年份
	  MONTH:英文全称的月份
	  mon:英文简写的月份
	  ddsp:英文的第几天(一个月的)
	  ddspth:英文序列数的第几天(一个月的)
	  DAY:全英文的星期
	  DY:简写的英文星期
	  hh:小时
	  mi:分钟
	  ss:秒

	例如:
	测试常见的一些日期数据转换为字符串的格式
	select to_char(sysdate,'yyyy MM D DD DDD YEAR MONTH ddsp ddspth DAY DY') from dual;

	select to_char(sysdate,'dd-mm-yy')
	from dual;

	select to_char(sysdate,'yy-mm-dd')
	from dual;

	select to_char(sysdate,'dd-mm-yy HH24:MI:SS AM')
	from dual;


  千年虫:
	在早期的计算机的程序中规定了的年份仅用两位数来表示。也就是说,假如是1971年,在计算机里就会被表示为71,但是到了2000年的时候这个情况就出现了问题,计算机就会将其年份表示为00。这样的话计算机内部对年份的计算就会出现问题。这个事情当时被称为千年虫

	数据库中表示日期中年份的有俩种: yy和rr
	之前一直使用的时候yy格式,后来才有的rr格式
	yy表示使用一个俩位数表示当前年份:
	1990 ---yy数据库格式---> 90
	1968 ---yy数据库格式---> 68
	1979 ---yy数据库格式---> 79
	
	rr格式表示: 
	如果日期中的年份采用的格式为rr,并且只提供了最后2位年份,那么年份中的前两位数字就由两部分共同确定:提供年份的两位数字(指定年),数据库服务器上当前日期中年份的后2位数字(当年)。确定指定年所在世纪的规则如下:
	规则1 如果指定年在00~49之间,并且当前年份在00~49之间,那么指定年的世纪就与当前年份的世纪相同。因此,指定年的前两位数字就等于当前年份的前两位数字。例如,如果指定年为15,而当前年份为2007,那么指定年就是2015。

	规则2 如果指定年在50~99之间,并且当前年份在00~49之间,那么指定年的世纪就等于当前年份的世纪减去1。因此,指定年的前两位数字等于当前年份的前两位数字减去1。例如,如果指定年为75,而当前年份为2007,那么指定年就是1975。

	规则3 如果指定年在00~49之间,并且当前年份在50~99之间,那么指定年的世纪就等于当前年份的世纪加上1。因此,指定年的前两位数字等于当前年份的前两位数字加上1。例如,如果指定年为15,而当前年份为2075,那么指定年就是2115。

	规则4 如果指定年在50~99之间,并且当前年份在50~99之间,那么指定年的世纪就与当前年份的世纪相同。因此,指定年的前两位数字就等于当前年份的前两位数字。例如,如果指定年为55,而当前年份为2075,那么指定年就是2055。

	注意:rr格式并没有完全的解决俩位数年份保存的问题,思考里面还有哪些问题存在。

	另外参照图片:rr日期格式规则.png



  to_char 把数字转换为字符
	例如:
    select to_char(salary,'$999,999.00') 
	from s_emp;

	fm表示去除结果显示中的开始的空格
	select to_char(salary,'fm$999,999.00') 
	from s_emp;

	L表示系统本地的货币符号
	select to_char(salary,'fmL999,999.00') 
	from s_emp;
	


  to_number 把字符转换为数字
	例如:
	select to_number('1000') 
	from dual;
	
	//这个写法是错的 abc不能转换为数字
	select to_number('abc')
	from dual;

	

  to_date 把字符转换为日期
	例如:
	select to_date('10-12-2019','dd-mm-yyyy')
	from dual;

	select to_date('25-5月-95','dd-month-yy')
	from dual;

	select to_date('95/5月/25','yy/month/dd')
	from dual;

	//session语言环境设置为英文下面可以运行
	select to_date('25-MAY-95','dd-MONTH-yy')
	from dual;

	alter session set nls_language=english;
	alter session set nls_language='simplified chinese';


	

oracle数据库中表示一个日期数据的几种方式
  1.使用sysdate
  2.使用oracle默认的日期格式 例如:'25-MAY-95'
  	注意要看当前的语言环境
  3.使用日期函数ADD_MONTHS/NEXT_DAY/LAST_DAY/ROUND/TRUNC
  4.使用转换函数to_date


函数之间的嵌套
  格式:F3(F2(F1(arg0,arg1),arg2),arg3)
  例如:
  先把'hello'和'world'连接起来,再转换为字母大写然后再从第4个字符开始,连着截取4个字符
  select substr(upper(concat('hello','world')),4,4)
  from dual;

第四章:多表查询

多表查询,又称表联合查询,即一条sql语句涉及到的表有多张,数据通过特定的连接进行联合显示.


笛卡尔积
	在数学中,两个集合X和Y的笛卡尓积(Cartesian product),又称直积,表示为X × Y.
	假设集合A={a, b},集合B={0, 1, 2},则两个集合的笛卡尔积为{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}。
	在数据库中,如果直接查询俩张表,那么其查询结果就会产生笛卡尔积
	例如:
	select *
	from s_emp,s_dept;
	

连接查询
	为了在多表查询中避免笛卡尔积的产生,我们可以使用连接查询来解决这个问题.
	连接查询分为:
		1.等值连接
		2.不等值连接
		3.外连接
			左外连接
			右外连接
			全连接
		4.自连接

等值连接
	利用一张表中某列的值和另一张表中某列的值相等的关系,把俩张表连接起来。
	例如:查询员工的名字、部门编号、部门名字
	select last_name,dept_id,name
	from s_emp,s_dept
	where s_emp.dept_id=s_dept.id;

	为了表述的更加清楚,可以给每张表起别名
	select se.last_name,se.dept_id,sd.id,sd.name 
	from s_emp se,s_dept sd
	where se.dept_id=sd.id;


不等值连接
	假设数据库中还有一张工资等级表:salgrade
	工资等级表salgrade:
		gradeName列表示等级名称
		losal	 列表示这个级别的最低工资数
		hisal    列表示这个级别的最高工资数

	表中的数据类似于下面内容:
	id  salgrade	losal hisal
	1  初级程序员   2000  4000
	2  中级程序员   4000  6000
	
	例如:
	查询出员工的名字、职位、工资、工资等级名称
	SELECT  e.last_name, e.title, e.salray, s.gradeName
	FROM    s_emp e, salgrade s
	WHERE   e.salray BETWEEN s.losal AND s.hisal


外连接
	外连接分为:左外连接 右外连接 全连接
	先分别在俩s_emp和s_dept表中插入新的数据
	特点:新员工tom不在任何部门,新增部门st下面没有任何员工
	insert into s_emp(id,last_name) values(26,'tom');
	insert into s_dept(id,name) values(60,'st');
	commit;

	下面条sql语句可以把上面插入的数据给删除掉
	delete from s_emp where id=26;
	delete from s_dept where id=60;
	commit;
	
	这个时候再使用等值连接的话,查询出来的数据就会少,因为新增的员工tom和部门表中的数据连接不上,当然新增的部门st也和员工表中的数据连接不上.那么这俩条数据都是在等值连接中查询不出来.


左外连接
	例如:
	查询所有员工 以及对应的部门的名字,没有部门的员工也要显示出来
	select last_name,dept_id,name 
	from s_emp,s_dept
	where s_emp.dept_id=s_dept.id(+);
	
	或者 俩者是等价的

	select last_name,dept_id,name 
	from s_emp left outer join s_dept
	on s_emp.dept_id=s_dept.id;
	
	注意:outer可以省去不写



右外连接
	例如:
	查询所有员工 以及对应的部门的名字,没有任何员工的部门也要显示出来
	select last_name,dept_id,name 
	from s_emp,s_dept
	where s_emp.dept_id(+)=s_dept.id;

	select last_name,dept_id,name 
	from s_emp right outer join s_dept
	on s_emp.dept_id=s_dept.id;

	注意:outer可以省去不写


全连接
	例如:
	查询所有员工 以及对应的部门的名字,没有任何员工的部门也要显示出来,没有部门的员工也要显示出来
	select last_name,dept_id,name 
	from s_emp full outer join s_dept 
	on s_emp.dept_id=s_dept.id;

	注意:outer可以省去不写


自连接
	一张表,自己和自己连接
	例如:
	查询每个员工的名字以及员工对应的管理者的名字
	select s1.last_name,s2.last_name manager_name
	from s_emp s1,s_emp s2
	where s1.manager_id = s2.id;



对查询结果集的操作
	如果有俩条sql语句,每一条sql都可以查询出一个结果,这个被称之为结果集。那么我们可以使用下面的关键字对俩个结果集进行操作
	union		取俩个结果集的并集 
	union all	把俩个结果集合在一起显示出来	
	minus    	第一个结果集除去第二个结果集和它相同的部分
	intersect	求俩个结果集的交集

	注意:前提条件 俩个结果集中查询的列要完全一致

union  取俩个结果集的并集 
	例如:
	select last_name,dept_id,name 
	from s_emp,s_dept
	where s_emp.dept_id=s_dept.id(+)
	union
	select last_name,dept_id,name 
	from s_emp,s_dept
	where s_emp.dept_id(+)=s_dept.id;

union all  把俩个结果集合在一起显示出来	
	例如:
	select last_name,dept_id,name 
	from s_emp,s_dept
	where s_emp.dept_id=s_dept.id(+)
	union all
	select last_name,dept_id,name 
	from s_emp,s_dept
	where s_emp.dept_id(+)=s_dept.id;

minus  第一个结果集除去第二个结果集和它相同的部分
	例如:
	select last_name,dept_id,name 
	from s_emp,s_dept
	where s_emp.dept_id=s_dept.id(+)
	minus
	select last_name,dept_id,name 
	from s_emp,s_dept
	where s_emp.dept_id(+)=s_dept.id;
	
	对比俩种情况的结果

	select last_name,dept_id,name 
	from s_emp,s_dept
	where s_emp.dept_id(+)=s_dept.id
	minus
	select last_name,dept_id,name 
	from s_emp,s_dept
	where s_emp.dept_id=s_dept.id(+);



intersect  求俩个结果集的交集
	select last_name,dept_id,name 
	from s_emp,s_dept
	where s_emp.dept_id=s_dept.id(+)
	intersect
	select last_name,dept_id,name 
	from s_emp,s_dept
	where s_emp.dept_id(+)=s_dept.id;



oracle中的伪列 rownum
	伪列rownum,就像表中的列一样,但是在表中并不存储。伪列只能查询,不能进行增删改操作。它会根据返回的结果为每一条数据生成一个序列化的数字.rownum是oracle才有的伪列

	rownum 所能作的操作:
	
	rownum 只能等于1  如果让其等于其他数 则查不到数据
	例如:
	select last_name
	from s_emp
	where rownum=1

	rownum 大于0      如果让其大于其他数 则查不到数据
	例如:
	select last_name
	from s_emp
	where rownum>0
	
	rownum 可以小于任何数
	例如:
	select last_name
	from s_emp
	where rownum<7

第五章:组函数

group by 在查询表中数据的时候进行分组的关键字
	思考:为什么要对数据进行分组
having   分组之后的进行进一步数据筛选的关键字
	having和where的功能类似

组函数(分组函数),是指将数据按照某列的值进行分组后,然后使用组函数分别对每个分好的小组中的数据进行处理。所以组函数一般要结合着分组关键字group来使用

组函数:
	avg       求平均值
	count     计算有多少条数据
	max       最大值
	min       最小值
	sum       求和

	stddev    标准差
	variance  方差


sql语句的各部分构成
	select   ....
	from	 ....
	where	 ....
	group by ...
	having	 ...
	order by ....
	
	注:除了select和from之外其他的都不是必须的。

	假如select..from..后面的语句都出现了,那么他们的执行顺序为:
	where-->group by分组-->执行组函数-->having筛选->order by


	组函数出现的位置: 
		1.select后面 
		2.having后面 
		3.order by后面
		4.where后面一定【不能】出现组函数

		注意:如果select/having语句后面出现了组函数,那么select/having后面没有被组函数修饰的列,就必须出现在group by 后面


	where和having对比:
	   1.where和having都是做条件筛选的
	   2.where执行的时间比having要早
	   3.where后面不能出现组函数
	   4.having后面可以出现组函数
	   5.where语句要紧跟from后面
	   6.having语句要紧跟group by后面

	group by和having的关系:
	   1.group by可以单独存在,后面可以不出现having语句
	   2.having不能单独存在,有需要的话,必须出现在group by后面

	order by语句
	   1.如果sql语句中需要排序,那么就一定要写在sql语句的最后面
	   2.order by后也可以出现组函数


使用组函数:不结合group分组使用
	注:如果不使用group分组的话,那么默认当前查询到的所有数据是一组
	例如:
	查询s_emp表中所有员工的平均工资
	select avg(salary)
	from s_emp;

	查询s_emp表中共有多少条数据
	select count(*)
	from s_emp;

	查询s_emp表中所有员工中的最大工资
	select max(salary)
	from s_emp;

	查询s_emp表中所有员工中的最小工资
	select min(salary)
	from s_emp;

	查询s_emp表中所有员工的工资总和
	select sum(salary)
	from s_emp;

	查询s_emp表中所有员工的工资的标准差
	select stddev(salary)
	from s_emp;

	查询s_emp表中所有员工的工资的方差
	select variance(salary)
	from s_emp;


使用组函数:结合group分组使用
	例如:
	查询s_emp表中每个部门的平均工资
	select dept_id,avg(salary)
	from s_emp
	group by dept_id;

	查询s_emp表中每个部门员工的最高工资
	select dept_id,max(salary)
	from s_emp
	group by dept_id;

	查询s_emp表中每个部门员工的工资总和
	select dept_id,sum(salary)
	from s_emp
	group by dept_id;

	查询s_emp表中每个部门员工的人数
	select dept_id,count(*)
	from s_emp
	group by dept_id;

	
	//分组之后使用各种组函数
	select dept_id,count(*),min(salary),max(salary),sum(salary),avg(salary)
	from s_emp
	group by dept_id;


使用组函数:结合group分组以及having筛选使用
	例如:
	查询s_emp表中部门的平均工资大于等于1400的部门
	select dept_id,avg(salary)
	from s_emp
	group by dept_id
	having avg(salary)>=1400;
	
	思考:上面的sql语句修改为如下,是否可以?

	select dept_id,avg(salary)
	from s_emp
	where avg(salary)>=1400
	group by dept_id;

	
	查询s_emp表中部门的总工资大于等于4000的部门
	select dept_id,sum(salary)
	from s_emp
	group by dept_id
	having sum(salary)>=4000;



使用组函数:其他实例
	例如:
	查询s_emp表中部门的平均工资大于等于1400的部门,并且显示出这些部门的名字,同时按照部门编号进行排序
	第一步:查询出基本需求
	select dept_id,avg(salary)
	from s_emp
	group by dept_id
	having avg(salary)>=1400
	order by dept_id;

	第二步:加入多表查询,并且分别给表起别名
	select se.dept_id,avg(se.salary)
	from s_emp se,s_dept sd
	group by se.dept_id
	having avg(se.salary)>=1400
	order by se.dept_id;

	第三步:查询出s_dept表中的部门名称,并且进行等值连接
	select se.dept_id,avg(se.salary),sd.name
	from s_emp se,s_dept sd
	where se.dept_id = sd.id
	group by se.dept_id
	having avg(se.salary)>=1400;
	order by se.dept_id;

	第四步:select语句后出现了组函数,那么没有被组函数修饰的列放到group by分组后面
	select se.dept_id,avg(se.salary),sd.name
	from s_emp se,s_dept sd
	where se.dept_id = sd.id
	group by se.dept_id,sd.name
	having avg(se.salary)>=1400
	order by se.dept_id;
	
	思考:是否可以把where后的条件筛选 转移 到having语句后面?


	查询s_emp表中最大的工资数,并且显示出这个最大工资的员工的名字
	第一步:查出最大工资数
	select max(salary)
	from s_emp;
	
	第二步:加上last_name的显示
	select last_name,max(salary)
	from s_emp;

	第三步:select后面出现组函数,没有被组函数修饰的列放到group by后面,但是发现查询结果并不是想要结果
	select last_name,max(salary)
	from s_emp
	group by last_name;
	
	第四步:修改为多表查询(起别名),从s1表中查询出最大的工资数是多少,然后再和s2表连接起来,选出s2表中这个最大工资数的员工名字
	select s2.last_name,max(s1.salary)
	from s_emp s1,s_emp s2
	where s2.salary = max(s1.salary)
	group by s2.last_name;
	
	第五步:where后面不能出现组函数,所以改为having
	select s2.last_name,max(s1.salary)
	from s_emp s1,s_emp s2
	group by s2.last_name,s2.salary
	having s2.salary = max(s1.salary);

	
	练习:
	查询s_emp表每个部门的最大工资数,并且显示出这个最大工资的员工名字以及该部门的名字和该部门所属区域,并且使用部门编号进行排序

第六章:子查询(嵌套查询)
子查询,即一个select语句中嵌套了另外的一个或者多个select语句

例如:
查询工资比Simth工资高的员工信息
	第一步:查询Smith的工资数
	select salary
	from s_emp
	where last_name='Smith';	
	结果:
		SALARY
	----------
		   940

	第二步:查询工资比940高的员工信息
	select last_name,salary
	from s_emp
	where salary>940;

	第三步:把第二步中的数字940替换成第一步中的sql语句即可(注意格式)
	select last_name,salary
	from s_emp
	where salary>(
		select salary
		from s_emp
		where last_name='Smith'
	);


例如:
查询所有部门的平均工资
select dept_id,avg(salary)
from s_emp
group by dept_id;

结果:
   DEPT_ID AVG(SALARY)
---------- -----------
		42  1081.66667
		43         900
		34        1160
		44        1050
		31        1400
		32        1490
		35        1450
		50        2025
		41      1247.5
		45        1089
		33        1515

   DEPT_ID AVG(SALARY)
---------- -----------
		10        1450


查询平均工资比1247.5高的部门编号
select dept_id
from s_emp
group by dept_id
having avg(salary)>1247.5;

结果:
   DEPT_ID
----------
		31
		32
		35
		50
		33
		10


查询平均工资比1247.5高的部门中员工信息
select last_name,salary,dept_id
from s_emp
where dept_id in(10,31,32,33,35,50);

等价于

select last_name,salary,dept_id
from s_emp
where dept_id in(
	select dept_id
	from s_emp
	group by dept_id
	having avg(salary)>1247.5
);



查询平均工资比 41号部门的平均工资 高 的部门中员工的信息
select avg(salary)
from s_emp
where dept_id=41;

结果:
AVG(SALARY)
-----------
	 1247.5

所以这个sql语句和1247.5是等价的,那么就可以将上面sql语句中的1247.5给替换了
select last_name,salary,dept_id
from s_emp
where dept_id in(
	select dept_id
	from s_emp
	group by dept_id
	having avg(salary)>1247.5
);
替换后为:
select last_name,salary,dept_id
from s_emp
where dept_id in(
	select dept_id
	from s_emp
	group by dept_id
	having avg(salary)>(
		select avg(salary)
		from s_emp
		where dept_id=41
	)
);


练习:
注意:(可以把子查询的结果作为一张表来使用)
查询平均工资比 41号部门的平均工资 高的部门中员工的信息,并且显示出当前部门的平均工资

查询平均工资比 41号部门的平均工资 高的部门中员工的信息,并且显示出当前部门的平均工资,同时显示出部门的名字



查询员工信息,这些员工的工资要比自己所在部门的平均工资高

查询员工信息,这些员工的工资要比自己所在部门的平均工资高,同时显示部门的名称以及所在地区



查询工资比 Ngao所在部门平均工资 要高的员工信息,同时这个员工所在部门的平均工资 也要 比Ngao所在部门的平均工资要高

查询工资比 Ngao所在部门平均工资 要高的员工信息,同时这个员工所在部门的平均工资 也要 比Ngao所在部门的平均工资要高,显示当前部门的平均工资

查询工资比 Ngao所在部门平均工资 要高的员工信息,同时这个员工所在部门的平均工资 也要 比Ngao所在部门的平均工资要高,显示当前部门的平均工资以及部门的名字和所在地区
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值