Java38: 数据库二(Oracle)
group by 分组
--每个工作的人数selectcount(job)fromempgroupbyjob;--有多少工作selectcount(coutn(job))fromempgroupbyjob;--每个工作的最高工资selectmax(sal)fromempgroupbyjob;--每个工作的最低工资selectmin(sal)fromempgroupbyjob;--每个工作的平均工资selectavg(sal)fromempgroupbyjob;--所有工作中最大的平均工资selectmax(avg(sal))fromempgroupbyjob;
使用having 根据条件过滤组
selectjob,count(job)fromempgroupbyjobhavingcount(job)>=3;
where 用在group by 之前
selectjob,count(job)fromempwheresal>1000groupbyjobhavingcount(job)>=3;
decode 函数
decode(value1if1then1if2then2...else)
decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值)
如果 value1=if1 返回then1
否则 如果 value1=if2 返回 then2
默认的返回值是else
selectdecode(sal,1600,'一千六',5000,'五千','其他')fromemp;--按照job的内容分类统计其中部门ID是30的人数selectjob,count(decode(DEPTNO,30,1,null))deptnofromempgroupby(job);--按照部门分类统计每个部门中工作是CLERK的人数selectdeptno,count(decode(job,'CLERK',1,null))countsfromempgroupby(deptno);--按照部门分类计算每个每部中工作是CLERK的平均工资selectdeptno,avg(decode(job,'CLERK',sal,null))CLERK_AVG_SALfromempgroupby(deptno);
insertintoempvalues(8000,'lmdtx','CLERK',8080,to_date('1980/09/09','yyyy/mm/dd'),30000,null,null);insertintoempvalues(8880,'dsy','CLERK',8980,to_date('1982/02/02','yyyy/mm/dd'),3000,null,null);
表的关联
外键 在一个表中 存着对应另外一张表的主键
连接表
1·笛卡尔积emp 表中 deptno 为空的查询不到
--emp表中的所有的行*dept中的所有的行select*fromemp,dept;--需要写过滤条件过滤掉不需要的select*fromemp,deptwhereemp.deptno=dept.deptno;select*fromempe.deptdwheree.deptno=d.deptno;
2·内连接 这个结果和笛卡尔积 用条件后的结果一样
inner join 和 join 一样(省略 inner) 默认就是 内连接
join...on...fromempeinnerjoindeptdone.deptno=d.deptno
两个表的一个外键的名字 和 另一张表的主键的名字一样
fromempinnerjoindeptusing(deptno)
select*fromempeinnerjoindeptdone.deptno=d.deptno;select*fromempinnerjoindeptusing(deptno);
3·外连接
1·左外连(左边表的数据必须是全都有的,没有的地方补null)
fromempleftouterjoindeptusing(deptno)
select*fromempleftouterjoindeptonemp.deptno=dept.deptno;selectename,nvl(dname,'还没有部门')fromemp2leftouterjoindept2using(deptno);
2·右外连
select*fromemprightouterjoindeptusing(deptno);--查询所有部门的名称和部门人数按人数的降序排selectdname,count(empno)numfromemp2rightjoindept2Using(deptno)groupbydnameorderbynumdesc;
3·全外连(全都有)
empfullouterjoindept
select*fromempfullouterjoindeptusing(deptno);--查询所有部门的名称以及部门的人数没有部门的人化为未分配selectnvl(dname,'未分配'),count(empno)fromemp2fullouterjoindept2using(deptno)groupbydnameorderbydname;selectnvl(dname,'未分配部门')部门名字,decode(count(empno),0,'未分配人手',count(empno))人数fromemp2fullouterjoindept2using(deptno)groupbydnameorderbydname;
4·自连接
selecte1.ename,e2.enamefromemp2e1innerjoinemp2e2one1.mgr=e2.empno;
selecte1.ename,e2.enamefromemp2e1leftjoinemp2e2one1.mgr=e2.empno;selectnvl(e1.ename,'没有手下'),e2.enameMGRfromemp2e1rightjoinemp2e2one1.mgr=e2.empno;selecte2.ename,decode(count(e1.ename),0,'没有手下',count(e1.ename))fromemp2e1rightjoinemp2e2one1.mgr=e2.empnogroupbye2.ename
子查询
用在where子句中,单行单列selecte1.enamefromemp2e1innerjoinemp2e2one1.mgr=e2.empnowheree2.ename='KING';selectdistinctdnamefromemp2e1joindept2d2ONe1.deptno=d2.deptnowheree1.enamelike'%S%';selectdnamefromdept2wheredeptnoin(selectdeptnofromemp2whereenamelike'%S%');
ANY() 任意一个
ALL() 所有
selectename,job,salfromemp2wheresal>all(selectDISTINCTsalfromemp2wherejob='MANAGER')andjob<>'MANAGER';selectenamejob,salfromemp2wheresal>any(selectdistinctsalfromemp2wherejob='CLERK')andjob<>'CLERK';
exists 用于判断后面的子查询是否有行 有true 没有false
selectenamefromemp2e1whereEXISTS(select1fromemp2e2wheree2.mgr=e1.empno);selectenamefromemp2e1wherenotexists(select1fromemp2e2wheree2.mgr=e1.empno);
3 in (1,2,3) true
3 in (1,2,null) false
5 not in (1,2,3) true
5 not in (1,2,null) false
5 in (1,2,null) false
5 not in (null) false
5in (null) false
not in 的子查询中不能出现null值
where 中的多列 查询
selecte.ename,e.sal,d.deptno,d.dnamefromemp2einnerjoindept2done.deptno=d.deptnowhere(e.deptno,e.sal)in(selectdeptno,min(sal)fromemp2wheredeptnoisnotnullgroupbydeptno);select*fromemp2where(deptno,sal)in(selectdeptno,min(sal)fromemp2wheredeptnoisnotnullgroupbydeptno);selectdeptno,min(sal)fromemp2wheredeptnoisnotnullgroupbydeptno;
用在having
fromempwheredeptnoisnotnullgroupbydeptnohavingavg(sal)<(selectmax(avg(sal))fromempgroupbydeptno)
selectmax(avg(sal))fromemp2groupbydeptno;
selectdeptno,round(avg(sal))fromemp2wheredeptnoisnotnullgroupbydeptnoHAVINGavg(sal)<(selectmax(avg(sal))fromemp2groupbydeptno);
selectdname,deptnofromemp2joindept2using(deptno)wheredeptnoisnotnullgroupbydeptno,dnamehavingavg(sal)=(selectmax(avg(sal))fromemp2groupbydeptno);
分页
伪列
selectempno,ename,rownumfromemp2orderbyename;
select*fromemp2whererownum<=10;
select*from(selectempno,ename,rownumnfromemp2whererownum<=10)wheren>5andn<=10
select*from(selectempno,ename,rownumnfromemp2)wheren>5andn<=10
select*from(selectempno,ename,rownumnfromemp2whererownum<=10)wheren>5
select*from(selectempno,ename,sal,rownumnfrom(select*fromemp2orderbysal)whererownum<=10)wheren>5;
内联视图(Inner View)
就是把select后的结果当作一张表
selectename名字,job职位,emp_num手下人数fromemp2join(selectdeptnod,count(empno)emp_numfromemp2innerjoindept2using(deptno)groupbydeptno)ondeptno=dwherejob='MANAGER';
selectename名字,job职位,dname部门,deptno部门编号,emp_num手下人数fromemp2innerjoin(selectdeptnod,count(empno)emp_num,dnamefromemp2innerjoindept2using(deptno)groupbydeptno,dname)ondeptno=dwherejob='MANAGER'
group by 对多个列分组
而这两个列都是对部门的唯一标识,不会影响分组
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。