标签:over 单行 结果 group 连续 ast 直接 oracl oracle
所谓子查询,实际上为查询的嵌套
当根据给出的条件无法直接查出所需要的数据时,需要用到子查询.
其中出现子查询最多的位置:
查询与7369同部门的所有人
SQL> select empno,ename,deptno
2 from emp
3 where deptno=
4 (select deptno from emp where empno=7369);
EMPNO ENAME DEPTNO
---------- -------------------- ----------
7777 S_HH%GGH 20
7369 SMITH 20
7566 JONES 20
7788 SCOTT 20
7876 ADAMS 20
7902 FORD 20
查询每个部门的人数
SQL> select
2 (select count(1) from emp where deptno=10) "10",
3 (select count(1) from emp where deptno=20) "20",
4 (select count(1) from emp where deptno=30) "30"
5 from dual;
10 20 30
---------- ---------- ----------
3 6 6
查询平均工资 少于20组的平均工资 的班组
SQL> select deptno, avg(sal)
2 from emp
3 group by deptno
4 having avg(sal) >
5 (select avg(sal) from emp where deptno = 20);
DEPTNO AVG(SAL)
---------- ----------
10 2916.66667
查询最高工资的的五人的成绩
SQL> select *
2 from (select sal from emp where sal > 0 order by sal desc)
3 where rownum < 6;
SAL
----------
5000
3000
3000
2975
2850
要求查询公司工资最低的员工姓名,班组信息
第一步:统计出公司的最低工资
SQL> select min(sal) from emp;
MIN(SAL)
----------
800
第二步:上面会返回单行单列数据,是一个数值.
再进行where条件判断
SQL> select ename,job,deptno from emp
2 where sal=(select min(sal) from emp);
ENAME JOB DEPTNO
-------------------- ------------------ ----------
SMITH CLERK 20
查询公司雇佣最早的雇员
雇佣最早一定是雇员日期最小,那么使用MIN()函数完成
SQL> select min(hiredate) from emp;
MIN(HIREDATE)
--------------
17-12月-80
返回单行单列的数据,所有可以直接在WHERE子句中使用
SQL> select empno,ename,hiredate from emp
2 where hiredate=(select min(hiredate) from emp);
EMPNO ENAME HIREDATE
---------- -------------------- --------------
7369 SMITH 17-12月-80
查询出与SMITH部门相同、职位相同的所有雇员的编号姓名信息
首先应该查询SMITH的部门与职位
SQL> select deptno,job from emp
2 where ename='SMITH';
DEPTNO JOB
---------- ------------------
20 CLERK
此时返回了单行两列的数据信息,要进行比较时要同时满足
SQL> select empno,ename,deptno,job from emp
2 where (deptno,job)=(
3 select deptno,job from emp where ename='SMITH');
EMPNO ENAME DEPTNO JOB
---------- -------------------- ---------- ------------------
7777 S_HH%GGH 20 CLERK
7369 SMITH 20 CLERK
7876 ADAMS 20 CLERK
在WHERE子句中提供有三个主要的运算符:IN、ANY、ALL
SQL> select * from sc;
SNO CNO SCORE
-------------------- -------------------- ----------
s001 c001 78.9
s002 c001 80.9
s003 c001 81.9
s004 c001 60.9
s001 c002 82.9
s002 c002 72.9
s003 c002 81.9
s001 c003 59
查询c001课程比c002课程成绩高的所有学生的学号
SQL> select sno
2 from sc t1
3 where t1.cno='c001'
4 and sno in
5 (select sno from sc where
6 cno='c002' and t1.score>score and t1.sno=sno);
SNO
--------------------
s002
查询c001课程比c002课程成绩高的所有学生的学号
SQL> select sno
2 from sc t1
3 where t1.cno='c001'
4 and exists(
5 select * from sc where
6 cno='c002' and t1.sno=sno and t1.score>score);
SNO
--------------------
s002
SQL> select * from sc;
SNO CNO SCORE
-------------------- -------------------- ----------
s001 c001 78.9
s002 c001 80.9
s003 c001 81.9
s004 c001 60.9
s001 c002 82.9
s002 c002 72.9
s003 c002 81.9
s001 c003 59
s004 c002 81.9
查出指定条件后的进行排名
使用这个函数,成绩相同的两名是并列,下一位同学空出所占的名次。
查询各科成绩前三名的记录
SQL> select cno,sno,score,
2 rank() over(partition by cno order by score desc) ranks from sc;
CNO SNO SCORE RANKS
-------------------- -------------------- ---------- ----------
c001 s003 81.9 1
c001 s002 80.9 2
c001 s001 78.9 3
c001 s004 60.9 4
c002 s001 82.9 1
c002 s003 81.9 2
c002 s004 81.9 2
c002 s002 72.9 4
c003 s001 59 1
SQL> select cno,sno,score from
2 (select cno,sno,score,rank() over(partition by cno order by score desc) rank from sc)
3 where rank<4;
CNO SNO SCORE
-------------------- -------------------- ----------
c001 s003 81.9
c001 s002 80.9
c001 s001 78.9
c002 s001 82.9
c002 s003 81.9
c002 s004 81.9
c003 s001 59
使用rank over()的时候,空值是最大的,如果排序字段为null, 可能造成null字段排在最前面,影响排序结果。
SQL> select deptno,comm,
2 dense_rank() over(partition by deptno order by comm desc) ranks
3 from emp
4 where deptno=30;
DEPTNO COMM RANKS
---------- ---------- ----------
30 1
30 1
30 1400 2
30 500 3
30 300 4
30 0 5
SQL> select deptno,comm,
2 dense_rank() over(partition by deptno order by comm desc nulls last) ranks
3 from emp
4 where deptno=30;
DEPTNO COMM RANKS
---------- ---------- ----------
30 1400 1
30 500 2
30 300 3
30 0 4
30 5
30 5
与rank() over的区别是:
两名学生的成绩并列以后,下一位同学并不空出所占的名次。
SQL> select cno,sno,score,
2 dense_rank() over(partition by cno order by score desc) ranks from sc;
CNO SNO SCORE RANKS
-------------------- -------------------- ---------- ----------
c001 s003 81.9 1
c001 s002 80.9 2
c001 s001 78.9 3
c001 s004 60.9 4
c002 s001 82.9 1
c002 s003 81.9 2
c002 s004 81.9 2
c002 s002 72.9 3
c003 s001 59 1
SQL> select cno,sno,score from
2 (select cno,sno,score,dense_rank() over(partition by cno order by score desc) rank from sc)
3 where rank<4;
CNO SNO SCORE
-------------------- -------------------- ----------
c001 s003 81.9
c001 s002 80.9
c001 s001 78.9
c002 s001 82.9
c002 s003 81.9
c002 s004 81.9
c002 s002 72.9
c003 s001 59
该函数不需要考虑是否并列,那怕根据条件查询出来的数值相同也会进行连续排名
SQL> select cno,sno,score,
2 row_number() over(partition by cno order by score desc) ranks from sc;
CNO SNO SCORE RANKS
-------------------- -------------------- ---------- ----------
c001 s003 81.9 1
c001 s002 80.9 2
c001 s001 78.9 3
c001 s004 60.9 4
c002 s001 82.9 1
c002 s003 81.9 2
c002 s004 81.9 3
c002 s002 72.9 4
c003 s001 59 1
SQL> select cno,sno,score from
2 (select cno,sno,score,row_number() over(partition by cno order by score desc) ranks from sc)
3 where ranks<4;
CNO SNO SCORE
-------------------- -------------------- ----------
c001 s003 81.9
c001 s002 80.9
c001 s001 78.9
c002 s001 82.9
c002 s003 81.9
c002 s004 81.9
c003 s001 59
标签:over 单行 结果 group 连续 ast 直接 oracl oracle
原文地址:https://www.cnblogs.com/inmeditation/p/11884433.html