createtable t1 (id char(1), g number(3)); createtable t2 (id char(1), g number(3)); createtable t3 (id char(1), g number(3)); INSERTINTO t1 VALUES('A',70); INSERTINTO t1 VALUES('B',80); INSERTINTO t1 VALUES('C',75); INSERTINTO t1 VALUES('D',90); INSERTINTO t2 VALUES('B',70); INSERTINTO t2 VALUES('D',50); INSERTINTO t2 VALUES('E',60); INSERTINTO t3 VALUES('A',90); INSERTINTO t3 VALUES('B',90); INSERTINTO t3 VALUES('E',55); INSERTINTO t3 VALUES('F',93); commit;
1
select nvl(t1.id,t2.id),t1.g g1 ,t2.g g2 from t1 fullouterjoin t2 on t1.id=t2.id;
1 2
select nvl(temp.id,t3.id),temp.g1 g1,temp.g2 g2,t3.g g3 from t3 fullouterjoin (select nvl(t1.id,t2.id) id,t1.g g1 ,t2.g g2 from t1 fullouterjoin t2 on t1.id=t2.id) temp on t3.id = temp.id;
2.SQL语句练习
列出平均总收入(工资+提成)最高的部门名称
1 2 3
select d.dname from (select deptno,avg(sal) num from emp groupby deptno) t, dept d where t.deptno=d.deptno and t.num=(selectmax(avg(NVL(COMM,0)+SAL)) num from emp groupby deptno);
列出部门工资中位数比公司工资中位数高的部门名称
1 2 3
select d.dname from (select deptno, median(sal) num from emp groupby deptno) t, dept d where t.deptno=d.deptno and t.num>(select median(sal) num from emp);
求底层员工(即没有直属下属)中工资最高的员工名字
先查出底层员工名单
1
select*from emp where empno notin(selectdistinct mgr from emp where mgr isnotnull );
1 2 3 4 5
select t.ename from (select*from emp where empno notin(selectdistinct mgr from emp where mgr isnotnull )) t where t.sal = (selectmax(sal) from (select*from emp where empno notin(selectdistinct mgr from emp where mgr isnotnull )));
列出部门的名称和部门内员工的不同工种数
1 2 3
select d.dname,t.jobcount from (select deptno, count(distinct job) jobcount from emp groupby deptno) t, dept d where t.deptno=d.deptno ;
求每年进入公司工作的员工数
1
select to_char(hiredate,'yyyy') year,count(distinct(ename)) count from emp groupby to_char(hiredate,'yyyy');
把每个部门工资最低的员工的工资调整到与该部门倒数第 2 一致(注意有并列的情况)
分组排序结果
1
select ename,sal,row_number() over (partitionby deptno orderby sal asc) sal_order,deptno from scott.emp;
复制了一份新的emp表emp3
1 2 3 4 5 6
update emp3 set sal = (select sal from (select*from (select ename,sal,row_number() over (partitionby deptno orderby sal asc) sal_order,deptno from emp) t where t.sal_order =2) t1 where t1.deptno = emp3.deptno ) where ename in (select ename from (select ename,sal,row_number() over (partitionby deptno orderby sal asc) sal_order,deptno from emp) t2 where t2.sal_order =1) ;
会发现出现表锁,如果设置ALTER SESSION SET ISOLATION_LEVEL=SERIALIZABLE时候,对deptno = 20进行修改也会出现表锁,若使用默认配置,则可以修改
由于oracle采用RC 隔离级别,通过 where 条件过滤之后,不符合条件的记录上的行锁,会释放掉(虽然这里破坏了“两阶段加锁原则”);但是RR隔离级别,通过 where 条件走非索引列过滤之后,即使不符合where条件的记录,也是会加行锁。所以从锁方面来看,RC(mysql)的并发应该要好于RR;可以减少一部分锁竞争,减少死锁和锁超时的概率。