1. 程式人生 > >資料庫前幾次作業 (對應練習資料初始化.sql)

資料庫前幾次作業 (對應練習資料初始化.sql)

select *
from emp;


select ename,sal
from EMp
where job like 'manager'


select ename,sal
from emp
where ename like '__O%' 
select Ename,sal ,job
from emp
where job in ('manager','salesman')


select ename,sal
from emp 
where DEPTNO in (select DEPTNO
from dept
where DNAME= 'accounting')
--????
select ename,sal
from emp inner join dept 
on emp.deptno=dept.deptno
where dname ='accounting'


--工資是所在部門平均工資之上的員工
select emp.ename,emp.sal,t.avgsal
from emp  join (select deptno,avg(sal) avgsal
from emp 
group by deptno) as t
    on emp.deptno = t.DEPTNO 
where emp.sal>t.avgsal
--??????為什麼不行   難道是因為t的平均工資是組分的  以部門號為組分標誌,不能再部門號外面使用


--with t as (select from  join on where ) .... 後面的都變成t了
--方法一(工資是所在部門平均工資之上的員工)
with t as (select deptno,avg(sal) avgsal
       from emp
       group by deptno)
select ename,sal,avgsal
from t inner join emp
on emp.deptno = t.deptno   --部門編號相同的連線到一行上,這是連線條件,where 是去掉行的條件,剛才的是決定兩個表中
where emp.sal>t.avgsal     --哪兩行可以放在一行
--方法2(工資是所在部門平均工資之上的員工)
select ename,sal,avgsal
from (select deptno,avg(sal) avgsal
       from emp
       group by deptno)t inner join emp
on emp.deptno = t.deptno   --部門編號相同的連線到一行上,這是連線條件,where 是去掉行的條件,剛才的是決定兩個表中
where emp.sal>t.avgsal     --哪兩行可以放在一行  要不然無法確定SELECT的  avg(sal)是哪裡的sal 


--相關子查詢的嘗試   注意很重要
select ename,job,sal,deptno
from emp


select emp.ename,emp.job,emp.sal,emp.deptno
from emp 
where emp.sal > (
  select avg(sal) 
  from emp t2
  where t2.deptno=emp.deptno  --依賴於外部查詢結果
--  group by deptno
);




--想得到每個職位的平均工資 姓名 工資  部門的平均工資  所在職位的平均工資
with deptinfo as (select deptno,avg(sal) deptavgsal
from emp
group by deptno
)
 ,jobinfo as (select job,avg(sal) jobavgsal
from emp
group by job 


)
select ename,sal,deptavgsal,jobavgsal
from emp join deptinfo on emp.deptno = deptinfo .DEPTNO 
      join jobinfo on EMP .job = jobinfo.job 
























with jobinfo as (select job,avg(sal) jobavgsal
from emp
group by job)
,deptinfo as  (select deptno,avg(sal) deptavgsal
       from emp
       group by deptno)
select ename,sal,deptavgsal,jobavgsal
from emp join jobinfo on emp.job = jobinfo.job
     join deptinfo on emp.deptno = deptinfo.deptno


select ename,sal
from emp
where sal>(select avg(sal) 
from emp t
where t.deptno = emp.deptno) 
--就相當於是組了  以部門號劃分的組


--avg是聚合狀態的,必須在group by的狀態才能使用
select ename,sal
from emp
where sal>(select avg(sal) 
from emp t
where t.deptno = 200) 


--相關子查詢   
(select avg(sal) 
from emp t
where t.deptno = emp.deptno) 




select ename,sal
from emp 
where sal>
(select avg(sal)
from emp t
where t.deptno=emp.deptno
group by deptno)


select ename,sal
from emp
where sal>(select avg(sal) 
from emp t
where t.deptno = 20
--group by deptno







with jobinfo as (select job,avg(sal) jobavgsal
from emp
group by job)
,deptinfo as  (select deptno,avg(sal) deptavgsal
       from emp
       group by deptno)


select ename,sal,(select avg(sal) 
from emp t
where emp.deptno = t.deptno
--group by deptno
)
deptavgsal,
(select avg(sal) 
from emp t
where emp.job = t.job
--group by job
)
jobavgsal
from emp 








   --有員工的部門編號  部門名稱
   select distinct deptno
   from emp


   select distinct emp.deptno,dname
   from emp join dept on dept.deptno=emp.deptno


   select  deptno,dname
   from dept 
--11
   select ename
   from emp
   where  comm is null
--12
select ename,sal,comm
from emp
where comm is not null 
--13
select ename,sal
from emp
order by sal desc
--14
select max(sal) as 最高工資,min(sal) as 最低工資
from emp
--15  
select avg(sal) as 平均工,sum(sal) as 總計工資
from emp
--16  16.顯示補助在員工中的發放比例、即有多少比例的員工有補助。
--(此題需注意兩個問題:1.select語句中進行除法如何保留小數點後資料。2.count函式如何處理null型資料。)
select count(comm is null )/count(*)
from emp
--17  顯示每種職業的平均工資
select job,avg(sal) as 職業平均工資
from emp
group by job
--18  18.顯示每個部門每種崗位的平均工資和最高工資。部門號在前面先排序工作  再排序部門號  ,部門號  在前面先排序部門號,再排序工作
select deptno,job,avg(sal),max(sal)
from emp
group by deptno,job
--19   顯示平均工資低於2500的部門號,平均工資及最高工資。
select deptno,avg(sal) as avgsal,max(sal)
from emp
group by deptno
having avg(sal)<2500
--20   20.上一條語句以平均工資升序排序。
select deptno,avg(sal),max(sal)
from emp
group by deptno
having avg(sal)<2500
order by avg(sal) asc
--21
select ename,sal,job,deptno
from emp
where sal>2500 or job = 'manager'
--22
        select ename,deptno,sal,hiredate
from emp
order by deptno asc,sal desc,hiredate asc 
--23
select dname,ename
from emp join dept on emp.deptno = dept.deptno
order by dname 
--24
select ename
from emp
where empno = (select mgr from emp where ename = 'scott')


--25      即使部門沒有員工也顯示部門名稱
   select dname,ename
   from emp right join dept
   on emp.DEPTNO = dept.DEPTNO
  --left join返回左表所有元素以及右表與左表匹配的元素
   --order by dname,ename
--26
select ename,sal,grade
from emp join salgrade
on sal between loSAL and hiSAL 
order by grade 
--
select ename,sal
from emp join dept
on emp.deptno = dept.deptno
--where emp.deptno = (select deptno from dept where dname = 'accounting')
where dept.dname = 'accounting'
--28
select ename,sal,job,deptno
from emp
where job in (
select job 
--from dept 
--join emp 
--on emp.deptno = dept.deptno 
from emp 
where emp.deptno = '10'
)
--29
select ename,sal,deptno
from emp
where sal>(select max(sal) from emp where deptno='30')
--有員工的部門名稱和辦公地點
select dname,loc
from dept
where deptno in (
select distinct deptno
from emp

)
--注意distinct 因為不加相當於笛卡爾乘積  變成有部門的員工   那麼最後就有多個員工屬於一個部門  那麼去掉其他列 就有多個部門
select distinct  dname,loc
from dept join emp
on emp.deptno = dept.deptno
--從部門表找到部門號和辦公地點   但是要去除沒有員工的部門  就尋找員工表中  部門號等於這個部門號是否有不為空的行  要是沒有  去掉最外層的部門表中的此行
--!!!!!!!!不懂   exist什麼
select dname,loc
from dept
where exists(
select *
from emp
where emp.deptno = dept.deptno

--找出沒有員工的部門   用差運算   有員工的部門減去沒有員工的部門
(
select distinct dname,loc
from dept
)


except
(select distinct  dname,loc
from dept join emp
on emp.deptno = dept.deptno)  
--將部門表和員工表聯合起來


(select '部門名稱',dname
from dept
)
union
 (
select '員工名稱',ename
from emp
)


--自連線問題   輸出姓名職位  老闆姓名職位(emp表的mgr代表老闆編號  )????為什麼
select emp.ename,emp.job,tmgr.ename,tmgr.job
from emp join emp as tmgr
on emp.mgr = tmgr.deptno


--寫出所有部門的部門名稱,員工人數,部門工資
--有員工的部門  加上沒有員工的部門
(select dept.deptno,dname,count(ename),avg(sal)
from dept join emp
on dept.deptno = emp.deptno
group by dept.deptno,dept.dname)
union
(
select dept.deptno,dname,'0','0'
from dept 
where not exists (
  select ename
  from emp
  where emp.deptno = dept.deptno
)
)




select dept.deptno,dname,count(*)
from dept join emp
on dept.deptno = emp.deptno
group by dept.deptno,dept.dname


select *
--沒有員工的部門
from dept
(select dname,loc
from dept
)
except
(select distinct  dname,loc
from dept join emp
on emp.deptno = dept.deptno)






select dname from emp join dept on dept.deptno=emp.deptno group by emp.deptno having count(*)>2


select dname from emp join dept on dept.deptno=emp.deptno group by dept.deptno,dname having count(*)>2
--聚合函式不能巢狀?????
select dname from emp join dept on dept.deptno=emp.deptno group by emp.deptno,dname having min(count(*))=3


select dname from emp join dept on dept.deptno=emp.deptno group by dept.deptno,dname having min(count(*))>2




select dname from emp,dept where dept.deptno=emp.deptno group by dname having count(*)>2
--前面有聚合函式  即使沒有group by後面也當做一個分組
select dname from emp join dept on dept.deptno=emp.deptno group by dname where count(*)>2






select dname from emp join dept on dept.deptno=emp.deptno where count(*)>=2 group by dname


select empno,(select avg(sal) from emp group by deptno) from emp


select empno,ename,sal from emp where deptno in(select deptno,sal from emp where sal>2000)


select empno,ename,(select max(sal) from emp as a where deptno=emp.deptno) from emp


select* from emp


select dname,(select count(*) from emp where emp.deptno=dept.deptno) from dept


select *
from emp join dept


select a.ename from emp natural join emp as a 
where a.ename='scott'


select empno,ename,(select max(sal) from emp as a where deptno=emp.deptno) from emp


select dname,(select * from emp where emp.deptno=dept.deptno) from dept


select *
from emp
group by deptno
--聚集函式忽略null  group by  order by任何可以放表示式的地方都可以放case end
select empno,sal,
case when sal>2500 then 'gao'
end comment
from emp


--部門名稱,員工數,工資總額,補助數,reseerch排第一  其他升序
with t as(
select dname,count(empno),sum(sal) sum_sal,sum(comm) sum_comm
from dept left join emp
on dept.DEPTNO =emp.DEPTNO 
group by dname
order by
case dname
when 'research' then 1
else 2 end,dname   --case有數字 排在order by 代表數字  select 裡面代表把選擇的東西變成這個數字
)
--再加上每一種對應職位有多少人???????、、、沒寫完  繼續寫
with s as
(select dept.DEPTNO deptnoo ,dname,job,count(job) count_job
from emp right join dept
on dept.DEPTNO =emp.DEPTNO 
group by dept.deptno,job ,dname
)
select dname,job
from t join s
on t.dname=s.DNAME 


select distinct job
from emp


group by dname
order by
case dname
when 'research' then 1 
else 2 end,dname
with s as(
select dept.deptno,dname,count(empno) count_empno,sum(sal) sum_sal,sum(comm) sum_comm
from dept left join emp
on dept.DEPTNO =emp.DEPTNO 
group by dname,dept.deptno
order by
case dname
when 'research' then 1
else 2 end,dname   --case有數字 排在order by 代表數字  select 裡面代表把選擇的東西變成這個數字
)


with t as select deptno,empno,case job when 'analyst'then 1 end analyst,
case job when 'clerk'then 1 end clerk,
case job when 'manager'then 1 end manager,
case job when 'president'then 1 end president,
case job when 'salesman'then 1 end salesman
from emp




select t.deptno,sum(analyst) sum_analyst,sum(clerk) sum_clerk,sum(manager) sum_manager,sum(president) sum_president,sum(salesman) sum_saleman
--,dname,count_empno,sum_sal,sum_comm
from t


select empno,deptno
,case job when 'ANALAYT' then 1 end ANALAYT --不滿足條件返回null
,case job when 'CLERK' then 1 end CLERK
,case job when 'MANAGER' then 1 end MANAGER
,case job when 'PRESIDENT' then 1 end PRESIDENT
,case job when 'SALESMAN' then 1 end SALESMAN
from emp)
select deptno,sum(ANALAYT) ANALATY --聚集函式忽略null
,sum(CLERK) CLERK
,sum(MANAGER) MANAGER
,sum(PRESIDENT) PRESIDENT
,sum(SALESMAN) SALESMAN
from a
group by deptno


 --join s on t.DEPTNO =s.DEPTNO 
group by deptno