1.连接查询

1.1 使用连接谓词指定的连接

介绍:

在连接谓词表示形式中,连接条件由比较运算符在WHERE子句中给出,将这种表示形式称为连接谓词表示形式,连接谓词又称为连接条件。

语法:

[<表名1.>] <列名1> <比较运算符> [<表名2.>] <列名2>

说明:

在连接谓词表示形式中,FROM子句指定需要连接的多个表的表名,WHERE子句指定连接条件,比较运算符有:<、<=、=、>、>=、!=、<>、!<、!>。
由于连接多个表存在公共列,为了区分是哪个表中的列,引入表名前缀指定连接列。例如,student.sno表示student表的sno列,score.sno表示score表的sno列。为了简化输入,SQL允许在查询中使用表的别名,可在FROM子句中为表定义别名,然后在查询中引用。

1.1.1 等值连接

介绍:

表之间通过比较运算符“=”连接起来,称为等值连接

示例:

查询学生的情况和选修课程的情况

SELECT student.*, score.*
  FROM student, score
  WHERE student.sno=score.sno;

1.1.2 自然连接

介绍:

在目标列中去除相同的字段名,称为自然连接

示例:

查询学生的情况和选修课程的情况

SELECT student.*, score.cno, score.grade
  FROM student, score
  WHERE student.sno=score.sno;

手动去除student与score表中都有的sno字段

1.1.3 自连接

介绍:

将同一个表进行连接,称为自连接

示例:

查询选修了“1201”课程的成绩高于学号为“121002”的成绩的学生姓名。

select a1.* from score a1,score a2
  where a1.cno='1201' and a2.cno='1201' and a2.sno='121002' and   a1.grade>a2.grade;

1.2 使用JOIN关键字指定的连接

语法:

<表名> <连接类型> <表名> ON <条件表达式>
| <表名> CROSS JOIN <表名>
| <连接表>

其中,的格式为:

<连接类型>::=
      [ INNER | { LEFT | RIGHT | FULL } [ OUTER ] CROSS JOIN

说明:
在以JOIN关键字指定连接的表示方式中,在FROM子句中用JOIN关键字指定连接的多个表的表名,用ON子句指定连接条件。
在连接类型中,INNER表示内连接,OUTER表示外连接,CROSS表示交叉连接,这是 JOIN关键字指定的连接的3种类型。

1.2.1 内连接

介绍:
内连接按照ON所指定的连接条件合并两个表,返回满足条件的行。
内连接是系统默认的,可省略INNER关键字。
示例:

查询学生的情况和选修课程的情况。

SELECT *
  FROM student INNER JOIN score ON student.sno=score.sno;

查询选修了数据库系统课程且成绩在84分以上的学生情况。

select st.sno,st.sname,co.cname,sc.grade
  from student st JOIN score sc ON st.sno=sc.sno JOIN course co ON sc.cno=co.cno
  where co.cname='数据库系统' and sc.grade>=84;

该语句采用多表内连接,省略INNER关键字

1.2.2 外链接

介绍:
在内连接的结果表,只有满足连接条件的行才能作为结果输出。外连接的结果表不但包含满足连接条件的行,还包括相应表中的所有行。外连接有以下3种:

  1. 左外连接(LEFT OUTER JOIN):结果表中除了包括满足连接条件的行外,还包括左表的所有行。
  2. 右外连接(RIGHT OUTER JOIN):结果表中除了包括满足连接条件的行外,还包括右表的所有行。
  3. 完全外连接(FULL OUTER JOIN):结果表中除了包括满足连接条件的行外,还包括两个表的所有行。

(1)左外连接

示例:

采用左外连接查询教师任课情况。

SELECT teacher.tname, course.cname
  FROM teacher LEFT JOIN course ON (teacher.tno=course.tno);

(2)右外连接

示例:

采用右外连接查询教师任课情况。

SELECT teacher.tname, course.cname
  FROM teacher RIGHT JOIN course ON (teacher.tno=course.tno);

(3)全外连接

示例:

采用全外连接查询教师任课情况。

SELECT teacher.tname, course.cname
  FROM teacher FULL JOIN course ON (teacher.tno=course.tno);

1.2.3 交叉连接

示例:

采用交叉连接查询教师和课程所有可能组合。

SELECT teacher.tname,course.cname
  FROM teacher CROSS JOIN course;

2.集合查询

介绍:
集合查询将两个或多个SQL语句的查询结果集合并起来,利用集合进行查询处理以完成特定的任务,使用四个集合操作符(Set Operator) UNION、UNION ALL、INTERSECT和MINUS,将两个或多个SQL查询语句结合成一个单独SQL查询语句。

集合操作符的功能:

语法:

<SELECT查询语句1>
{UNION | UNION A LL | INTERSECT | MINUS}
<SELECT查询语句2>

说明:

在集合查询中,需要遵循的规则为:

  1. 在构成复合查询的各个单独的查询中,列数和列的顺序必须匹配,数据类型必须兼容。
  2. 用户不许在复合查询所包含的任何单独的查询中使用ORDER BY子句。
  3. 用户不许在BLOB、LONG等大数据对象上使用集合操作符。
  4. 用户不许在集合操作符SELECT列表中使用嵌套表或者数组集合。

2.1 并 UNION

介绍:

UNION语句将第一个查询中的所有行与第二个查询的所有行相加,消除重复行并且返回结果。

示例:

查询所有女教师和女学生的姓名、性别和出生日期。

SELECT tname, tsex, tbirthday
  FROM teacher
  WHERE tsex='女'
UNION
SELECT sname, ssex, sbirthday
  FROM student
  WHERE ssex='女';

2.2 并 UNION ALL

介绍:

UNION ALL语句将第一个查询中的所有行与第二个查询的所有行相加,UNION ALL不会从列表中滤除重复行。

示例:

查询性别为女及选修了课程号为4002的学生,不滤除重复行。

SELECT sno, sname, ssex
  FROM student
  WHERE ssex='女'
UNION ALL
SELECT a.sno, a.sname, a.ssex
  FROM student a, score b
  WHERE a.sno=b.sno AND b.cno='4002';

2.3 交 INTERSECT

介绍:

INTERSECT操作会获取两个查询,对值进行汇总,并且返回同时存在于两个结果集中的行。

示例:

查询既选修了课程号为8001又选修了课程号为4002的学生的学号、姓名、性别。

SELECT a.sno AS 学号, a.sname AS 姓名, a.ssex AS 性别
  FROM student a, score b
  WHERE a.sno=b.sno AND b.cno='8001'
INTERSECT
SELECT a.sno AS 学号, a.sname AS 姓名, a.ssex AS 性别
  FROM student a, score b
  WHERE a.sno=b.sno AND b.cno='4002';

查询既选修了课程名含有”数据库”又选修了课程名含有”数学”且性别为”男”的学生的学号、姓名、性别和班号。

SELECT a.sno AS 学号, a.sname AS 姓名, a.ssex AS 性别, a.sclass AS 班号
  FROM student a, course b, score c
  WHERE a.sno=c.sno AND b.cno=c.cno AND b.cname like '%数据库%' AND a.ssex='男'
INTERSECT
SELECT a.sno AS 学号, a.sname AS 姓名, a.ssex AS 性别, a.sclass AS 班号
  FROM student a, course b, score c
  WHERE a.sno=c.sno AND b.cno=c.cno AND b.cname like '%数学%' AND a.ssex='男';

2.4 差 MINUS

介绍:

MINUS集合操作会返回所有从第一个查询中有但是第二个查询中没有的那些行。

示例:

查询既选修了课程号为8001又未选修课程号为4002的学生的学号、姓名、性别。

SELECT a.sno AS 学号, a.sname AS 姓名, a.ssex AS 性别
  FROM student a, score b
  WHERE a.sno=b.sno AND b.cno='8001'
MINUS
SELECT a.sno AS 学号, a.sname AS 姓名, a.ssex AS 性别
  FROM student a, score b
  WHERE a.sno=b.sno AND b.cno='4002';

查询既选修了英语又未选修数字电路的学生的姓名、性别、出生日期和班号。

SELECT a.sname AS 姓名, a.ssex AS 性别, a.sbirthday AS 出生日期, a.sclass AS 班号
  FROM student a, course b, score c
  WHERE a.sno=c.sno AND b.cno=c.cno AND b.cname='英语'
MINUS
SELECT a.sname AS 姓名, a.ssex AS 性别, a.sbirthday AS 出生日期, a.sclass AS 班号
  FROM student a, course b, score c
  WHERE a.sno=c.sno AND b.cno=c.cno AND b.cname='数字电路';

3.子查询

介绍:
使用子查询,可以用一系列简单的查询构成复杂的查询,从而增强SQL语句的功能。
在SQL语言中,一个SELECT-FROM-WHERE语句称为一个查询块。在WHERE子句或HAVING子句所指定条件中,可以使用另一个查询块的查询的结果作为条件的一部分,这种将一个查询块嵌套在另一个查询块的子句指定条件中的查询称为嵌套查询。例如:

SELECT *
  FROM student
  WHERE sno IN
    (SELECT sno
       FROM score
       WHERE cno='1004'
     );

下层查询块“SELECT stno FROM score WHERE cno='203'”的查询结果,作为上层查询块“SELECT * FROM student WHERE stno IN”的查询条件,上层查询块称为父查询或外层查询,下层查询块称为子查询(Subquery)或内层查询,嵌套查询的处理过程是由内向外,即由子查询到父查询,子查询的结果作为父查询的查询条件。

3.1 IN子查询

介绍:
在IN子查询中,使用IN谓词实现子查询和父查询的连接。
语法:

<表达式> [ NOT ] IN ( <子查询>)

说明:
在IN子查询中,首先执行括号内的子查询,再执行父查询,子查询的结果作为父查询的查询条件。
当表达式与子查询的结果集中的某个值相等时,IN谓词返回TRUE,否则返回FALSE;若使用了NOT,则返回的值相反。
示例:

查询选修了课程号为8001的课程的学生情况。

SELECT *
FROM student
WHERE sno IN
  (SELECT sno
    FROM score
    WHERE cno='8001'
   );

查询未选修数字电路课程的学生情况。

select * from student where sno NOT IN
  (select sno from score where cno in
    (select cno from course where cname='数字电路'));

查询选修某课程的学生人数多于4人的教师姓名。

select teacher.tname from teacher where tno in
(select tno from course where cno in
  (select cno from score GROUP BY cno HAVING count(sno)>=4));

查询在计算机专业任课的教师情况。

select teacher.* from teacher where tno in
  (select c.tno from student a,score b,course c
    where a.sno=b.sno and b.cno=c.cno and a.speciality='计算机');

3.2 比较子查询

介绍:

比较子查询是指父查询与子查询之间用比较运算符进行关联。

语法:

<表达式> { < | <= | = | > | >= | != | <>  } { ALL | SOME | ANY } ( <子查询> )

说明:
关键字ALL、SOME和ANY用于对比较运算的限制,ALL指定表达式要与子查询结果集中每个值都进行比较,当表达式与子查询结果集中每个值都满足比较关系时,才返回TRUE,否则返回FALSE;SOME和ANY指定表达式要只与子查询结果集中某个值满足比较关系时,就返回TRUE,否则返回FALSE。

3.2.1 ALL

示例:

查询比所有计算机专业学生年龄都小的学生。

SELECT *
  FROM student
  WHERE sbirthday >ALL
    (SELECT sbirthday
       FROM student
       WHERE speciality='计算机'
    );

3.2.2 ANY SOME

示例:

查询课程号8001的成绩高于课程号4002成绩的学生。

select * from score where cno='8001' and grade> ANY(select grade from score where cno='4002');
select * from score where cno='8001' and grade> SOME(select grade from score where cno='4002');

ANY与SOME用法和结果一模一样

3.3 EXISTS子查询

介绍:
在EXISTS子查询中,EXISTS谓词只用于测试子查询是否返回行,若子查询返回一个或多个行,则EXISTS返回TRUE,否则返回FALSE,如果为NOT EXISTS,其返回值与EXIST相反。
语法:

[ NOT ] EXISTS ( <子查询> )

说明:
在EXISTS子查询中,父查询的SELECT语句返回的每一行数据都要由子查询来评价,如果EXISTS谓词指定条件为TRUE,查询结果就包含该行,否则该行被丢弃。

示例:

查询选修1004课程的学生姓名。

SELECT sname AS 姓名
  FROM student
  WHERE EXISTS
    (SELECT *
       FROM score
       WHERE score.sno=student.sno AND cno='1004'
     );

4.综合训练

(1)查询选修数据库系统课程的学生的姓名、性别、班级和成绩。

select a.sname,a.ssex,a.sclass,b.grade from student a,score b,course c
  where a.sno=b.sno and b.cno=c.cno and c.cname='数据库系统';

(2)查找选修了8001课程且为计算机专业学生的姓名及成绩,查出的成绩按降序排列。

select a.sname,b.grade from student a,score b
  where a.sno=b.sno ORDER BY b.grade DESC;

(3)查询既选修了英语又未选修数据库系统的学生的学号、姓名、出生日期和专业。

select a.sno,a.sname,a.sbirthday,a.speciality from student a,score b,course c
  where a.sno=b.sno and b.cno=c.cno and c.cname='英语'
MINUS
select a.sno,a.sname,a.sbirthday,a.speciality from student a,score b,course c
  where a.sno=b.sno and b.cno=c.cno and c.cname='数据库系统';

(4)查找学号为124001,课程名为”高等数学”的学生成绩。

select grade from score b,course c
  where b.cno=c.cno and c.cname='高等数学' and b.sno='124001';
select score.grade from score JOIN course ON score.cno=course.cno
  where course.cname='高等数学' and score.sno='124001';
select * from score
  where sno='124001' and cno in (select cno from course where cname='高等数学');

5.应用题

(1)查询选修了“英语”的学生姓名及成绩。

select a.sname,b.grade from student a,score b,course c
  where a.sno=b.sno and b.cno=c.cno and c.cname='英语';

(2)查询选修了“高等数学”且成绩在80分以上的学生情况。

select a.sname as 学生姓名,b.grade as 分值 from student a,score b,course c
  where a.sno=b.sno and b.cno=c.cno and c.cname='高等数学' and b.grade>=80;

(3)查询选修某课程的平均成绩高于85分的教师姓名。

select tname from teacher where tno in
  (select tno from course where cno in
    (select cno from score GROUP BY cno HAVING avg(grade)>=85)); 

(4)查询既选修了‘1201’号课程,又选修过‘1004’号课程的学生姓名、性别和总学分。

select a.sname,a.ssex,a.tc
  from student a, score b where a.sno=b.sno and b.cno='1201'
intersect
select sname,ssex,tc
  from student where sno in(select sno from score where cno='1004');

(5)查询既选修了‘1201’号课程,又未选修过‘1004’号课程的学生姓名、性别和总学分。

select a.sname,a.ssex,a.tc
    from student a, score b where a.sno=b.sno and b.cno='1201'
MINUS
select sname,ssex,tc
    from student where sno in(select sno from score where cno='1004');

(6)查询每个专业最高分的课程名和分数。

select c.cname,d.maxgrade
  from course c,(select cno,MAX(grade) maxgrade from score GROUP BY cno) d where c.cno=d.cno;

(7)查询通信专业的最高分。

思路:
1.选修通信专业的学生
​ select distinct b.sno from student a,score b where a.sno=b.sno and a.speciality='通信'
2.选修通信专业的学生的所有成绩
select * from score
​ where sno in (select distinct b.sno from student a,score b where a.sno=b.sno and a.speciality='通信');
3.选修通信专业的最高分

select MAX(grade) as 通信专业的最高成绩  from score
      where sno in (select distinct b.sno from student a,score b where a.sno=b.sno and a.speciality='通信');
select max(grade) as 最高分
  from student a,score b
  where a.sno=b.sno and a.speciality='通信' GROUP BY a.speciality;

(8)查询数据库系统课程的任课教师名称。

select teacher.* from teacher where tno in
  (select c.tno from course c where c.cname='数据库系统');

(9)查询学生成绩高于平均分的学号,课程号及成绩。

select sno as 学号,cno as 课程号,grade as 成绩 from score
  where grade >(select AVG(grade) from score) ;

(10)查询既选修了课程名含有”数据库”又选修了课程名含有”数学”且性别为”男”的学生的学号、姓名、性别和班号。

select a.sno,a.sname,a.ssex,a.sclass
  from student a JOIN score b ON a.sno=b.sno JOIN course c ON b.cno=c.cno
  where c.cname like '%数据库%' and a.ssex='男'
INTERSECT
select a.sno,a.sname,a.ssex,a.sclass
  from student a JOIN score b ON a.sno=b.sno JOIN course c ON b.cno=c.cno
  where c.cname like '%数学%' and a.ssex='男';

(11)查询出每个部门的编号、名称、位置、部门人数、平均工资。

思路:
1.根据员工表查询部门编号、部门人数和平均工资
select deptno,COUNT(*) as deptTotal,AVG(sal) as avgSal from emp GROUP BY deptno
2.根据部门编号查询具体的部门信息

select a.deptno 编号,a.dname 名称,a.loc 位置,b.depttotal 平均工资,b.avgsal 平均工资 from dept a,
  (select deptno,COUNT(*) as deptTotal,AVG(sal) as avgSal from emp GROUP BY deptno) b where a.deptno=b.deptno;

(12)找出其它部门比20号部门某员工工资高的雇员信息。

思路:
1.查询20号部门的所有工资
select sal from emp where deptno='20';
2.查询不在20号部门的员工工资任意大于(1)
*/

select * from emp where deptno NOT IN (20) and sal > SOME (select sal from emp where deptno='20');

(13)查询员工工资在MANAGER职位工资范围的员工信息。

select * from emp where job !='MANAGER' and
  sal >=(select MIN(sal) minSal from emp where job ='MANAGER');

(14)查询高出公司平均工资的全部雇员的信息。

select * from emp where sal >= (select AVG(sal) avgSal from emp);

(15)查询与SMITH在同一部门的员工信息。

select * from emp where ename !='SMITH' and deptno = (select deptno from emp where ename='SMITH');

03-oracle中的高级查询的更多相关文章

  1. 对于Oracle中分页排序查询语句执行效率的比较分析

    转自:http://bbs.csdn.net/topics/370033478 对于Oracle中分页排序查询语句执行效率的比较分析 作者:lzgame 在工作中我们经常遇到需要在Oracle中进行分 ...

  2. mybatis中的高级查询

    Mybatis作为一个ORM框架,肯定是支持sql高级查询的. 下面的一个案例来为大家详细讲解mybatis中的高级查询. 案例说明: 此案例的业务关系是用户,订单,订单详情与商品之间的关系. 以订单 ...

  3. oracle中使用sql查询时字段为空则赋值默认

    转至:http://www.th7.cn/db/Oracle/201501/86125.shtml oracle 通过 nvl( )函数sql 查询时为 空值 赋默认值 oracle 函数介绍之nvl ...

  4. Oracle中的层次查询详解

    1 语法格式 select [level], column, expr... from table [where condition] start with condition connect by ...

  5. ORACLE中的TOP-N查询(TOP-N分析)、分页查询

    TOP-N查询(TOP-N分析):就是获取某一数据集合中的前N条记录,实际应用中经常用到. Oracle中不支持SELECT TOP语句(MySQL中也没用此语句),需要借助ROWNUM伪列来实现TO ...

  6. oracle中的连接查询与合并查询总结

    连接查询: 连接查询是指基于多张表或视图的查询.使用连接查询时,应指定有效的查询条件,不然可能会导致生成笛卡尔积.如现有部门表dept,员工表emp,以下查询因查询条件无效,而产生笛卡尔积:   (各 ...

  7. Oracle数据库——SQL高级查询

    一.涉及内容 1.掌握SELECT语句的多表连接查询. 2.掌握SELECT语句的子查询. 二.具体操作 (一)根据Oracle数据库scott方案下的emp表和dept表,完成下列操作: 1.查询所 ...

  8. Oracle中的一些查询语句及其执行顺序

    查询条件: 1)LIKE:模糊查询,需要借助两个通配符,%:表示0到多个字符:_:标识单个字符. 2)IN(list):用来取出符合列表范围中的数据. 3)NOT IN(list): 取出不符合此列表 ...

  9. mysql中的高级查询

    以前学习的查询语法: select 字段名 from 表名 where 条件 其实,查询的语法变化很多: 1. select 可以查询表达式, 表达式就是 运算符+操作数. 比如 1 + 1 2 * ...

随机推荐

  1. APP请求服务器数据-HttpUrlConnection

    1. 实例化URL对象 首先第一步实例化一个URL对象,传入参数为请求的数据的网址. URL url = new URL("http://www.imooc.com/api/teacher? ...

  2. VS OpenCV imread imwrite nameWindow等相关报错问题

    排查过程 1. 项目属性C++目录中,包含库include 和 lib 目录了吗? 去自己的opencv安装目录中找到include 和 lib(一般在x64下有两个vc14/vc15, 我的是4.0 ...

  3. docker部署postgresql时,data目录不生效的问题探究

    今天用docker部署postgresql,用的是官方的镜像.结果挂载完 /var/lib/postgresql/data目录后,和容器里的目录其实并没有挂载成功. 母机上的目录并没有成功挂载到容器里 ...

  4. IIS发布的网站,内网和外网不能访问的解决办法

    A.关闭防火墙.控制面板-Windows防火墙-打开或关闭Windows防火墙(不推荐) B.打开:控制面板-Windows防火墙-高级设置-入站规则,在入站规则窗口中找到”BranchCache内容 ...

  5. row_number() over()分页查询

    1.首先讲下row_number() over() 是干什么的? 是一个分析函数,会在数据表生成一个排序列. 案例SQL: select ROW_NUMBER() over(order by book ...

  6. Oracle函数——日期函数

    Oracle中的时间类型只有date和TIMESTAMP,TIMESTAMP是比date更精确的类型.日期时间函数用于处理时间类型的数据,Oracle以7位数字格式来存放日期数据,包括世纪.年.月.日 ...

  7. 转://从一条巨慢SQL看基于Oracle的SQL优化

    http://mp.weixin.qq.com/s/DkIPwbDKIjH2FMN13GkT4w 本次分享的内容是基于Oracle的SQL优化,以一条巨慢的SQL为例,从快速解读SQL执行计划.如何从 ...

  8. mysql中将多行数据合并成一行数据

    .1GROUP_CONCAT()中的值为你要合并的数据的字段名; SEPARATOR 函数是用来分隔这些要合并的数据的: ' '中是你要用哪个符号来分隔: 2.必须要用GROUP BY 语句来进行分组 ...

  9. HTTP 1.1状态代码及其含义说明

    100  Continue  初始的请求已经接受,客户应当继续发送请求的其余部分.(HTTP 1.1新)   101  Switching Protocols  服务器将遵从客户的请求转换到另外一种协 ...

  10. Matrix Completion with Noise

    目录 引 恢复1 核范数与SDP 稳定恢复 Candes E J, Plan Y. Matrix Completion With Noise[J]. arXiv: Information Theory ...