SQL题目整理

一、emp表,求部门内(DEPTNO)最高的总薪资(sal+comm)的 部门,姓名,总薪资,要求使用三种方法实现

1、第一种方法

使用开窗函数套用子查询 查询出每个部门的最高工资

select 
	deptno
	,ename
	,t_sal
from 
(
		select
		deptno
		,ename
		,sal+nvl(comm,0) as t_sal
		,rank() over(partition by deptno order by sal+nvl(comm,0) desc) as rn 
	from 
		emp
) a
where  rn = 1

2、第二种方法

使用max开窗求出每个组的最高工资,再求出每个人的工资,嵌套子查询,若出现个人工资等于最高工资,即那个人为最高工资。

select 
	deptno
	,ename
	,sal
from
(
		select
		deptno
		,ename
		,sal+nvl(comm,0) as sal
		,max(sal+nvl(comm,0)) over(partition by deptno order by sal+nvl(comm,0) desc) as sal1
	from 
		emp
) 
where sal = sal1

3、第三种方法

第三种方法主要采用两表关联的方法,先查询出每个部门的最高工资,和emp表进行关联最终求出所要的结果。

select 
	t1.deptno
	,t1.ename
	,t2.m_sal
from 
emp t1 
join 
(
		select 
		deptno
		,max(sal+nvl(comm,0)) m_sal
		from 
			emp 
		group by  deptno
) t2 
on t1.sal+nvl(t1.comm,0) = t2.m_sal and t1.deptno = t2.deptno

二 、 emp表求部门内个人薪资(sal)大于部门平均薪资的人的部门,姓名,薪资,以及部门平均薪资,要求用两种方法实现(自关联和开窗函数)

1、自关联实现

select 
	t1.deptno
	,t1.ename
	,t1.sal
	,t2.avg_sal
from emp t1 
join
(
		select
			deptno
		 ,avg(sal)  avg_sal 
		from emp
		group by  deptno 
) t2 
on t1.deptno = t2.deptno 
where t1.sal > t2.avg_sal 

2、开窗函数实现

select 
*
from 
(
	select
		deptno
		,ename
		,sal
		,avg(sal) over(partition by deptno) as avg_sal
	from 
		emp 
)
where sal > avg_sal

三 、 emp 表 ,求同部门,按照薪资(sal)从大到小排名,排名上一位和排名下一位分别是多少薪资

select 
	deptno 
	,sal 
	,lead(sal,1) over(partition by deptno order by sal desc) as lead_sal --下一位
	,lag(sal,1) over(partition by deptno order by sal desc) as lag_sal   -- 上一位
from emp

四、rows between 的用法

rows between一般和 sum累加一起使用  主要的作用是用来控制累加的范围

用法模板一般如下:

SELECT
	sid,
	,day_time
	,sale_volume,
	,sum( sale_volume ) over ( orderby day_time rows between 2 preceding and current row )
FROM
	TT

例如对上面这一段代码解释: 为 当前行和前两行的累加

主要如下:

unbounded   preceding  第一行
2  preceding  前二行

2  following  后两行
unbounded following  最后一行

current  row当前行

搭配解释 

 rows between unbounded   preceding and current  row   当前行和之前的累加

 rows between 2  preceding and current  row   当前行和其前2行的累加

 rows between current  row and  2  following  当前行和其后2行的累加

 rows between current  row and  unbounded following  当前行和其后所有行的累加

五 、 emp表 sal数字向百位取整,例如6变成100,648变成700,1100变成1200,至少两种方法。

1、第一种方法

SELECT
	floor( ( sal + 100 ) / 100 ) * 100 
FROM
	emp

2、第二种方法

使用trunc,trunc(n,p):直接截断,与round类似,但不进行四舍五入

SELECT
	trunc( sal,- 2 ) +100
FROM
	emp

 六、求取sal,sal+100,和五中变化后的sal,取其中的最大值和最小值

SELECT
	GREATEST( sal, sal1, sal2 ) AS max_sal,
	LEAST( sal, sal1, sal2 ) AS min_sal 
FROM
	( SELECT sal, sal + 100 AS sal1, trunc( sal,- 2 ) + 100 AS sal2 FROM emp )

七、emp表,入职日期(hiredate)是当年的第几天,当月的第几天,当周的第几天 

SELECT
	HIREDATE - trunc( HIREDATE, 'yyyy' ) + 1  as year_day 
	,HIREDATE -trunc( HIREDATE, 'mm' ) +1 as month_day
	,to_char(HIREDATE,'d')  as week_day  --星期天为第一天
FROM
	emp

八、emp表递归问题,要求最后查询形式如下

 

with tmp(empno,ename,mgr,leve,tree)  as 
(
     select   empno,ename,mgr,1 as leve ,ename as tree from emp where mgr is null 
     union all
     select t1.empno  as empno, t1.ename as ename,t1.mgr as mgr ,(t2.leve +1) as leve,t1.ename||'-'||t2.tree as tree
     from emp t1
     join tmp t2
     on t1.mgr = t2.empno
)
select empno,ename,leve , tree from tmp

你可能感兴趣的:(一些SQL题或者JAVA题,sql,数据库,dba)