数据库应用技术授课单位:软件技术教研组第六讲高级查询高级查询的概述等值与非等值连接查询自然连接自身连接查询外连接查询复合连接条件查询子查询第六讲高级查询高级查询的概述笛卡儿乘积__不带连接谓词的连接,两个表元组的交叉乘积。又称为非限制连接查询。结果集的列为两个表属性列的和。9行(结果)=3行(表1)*3行(表2)产品编号0001显示器0002键盘0004鼠标产品编号销量000125000330000535产品名称①②③第六讲高级查询高级查询的概述产品编号产品名称产品编号销量0001显示器0001250002键盘0001250004鼠标0001250001显示器0003300002键盘0003300004鼠标0003300001显示器0005350002键盘0005350004鼠标000535►第六讲高级查询高级查询的概述一般情况下笛卡儿乘积返回的结果大多数是冗余的,没有实际的应用意义的,所以这种连接世界使用的很少。所以要避免笛卡儿乘积的出现,给出where条件来限制查询结果。等值与非等值连接查询自身连接查询外连接查询复合连接条件查询第六讲高级查询等值与非等值连接查询连接查询过程当中,连接两个表的条件为“=”时,称为等值连接。使用其他运算符的连接成为非等值连接。等值连接运算符:=非等值连接运算符:,,=,=,!=在连接查询的过程当中,可以根据实际情况使用任意的合法的条件运算符(逻辑条件、确定范围、确定集合、字符匹配等条件)。等值连接的过程类似于交叉连接,只是在连接的过程当中只拼接满足条件的记录到结果集当中。第六讲高级查询等值与非等值连接查询等值连接的基本语法:SELECT列名列表FROM表名1[INNER]JOIN表名2ON表名1.列名=表名2.列名[INNER]:可选关键字,指定连接类型为内连接。表名1JOIN表名2:等值连接对象的连接体。ON表名1.列名=表名2.列名:是等值连接的连接条件,通常情况下为“ON主键=外键”。第六讲高级查询等值与非等值连接查询例:用等值连接的方法连接“产品”表和“产品销售”表,代码如下:USESTUDENTGOSELECT*FROM产品JOIN产品销售ON产品.产品编号=产品销售.产品编号第六讲高级查询等值与非等值连接查询通过上面的例子可以看到在结果集当中“产品编号”为重复列,在等值连接中,把目标列中重复的列去掉则为自然连接。例:自然连接产品表和产品销售表。代码如下:SELECT产品.产品编号,产品名称,销量FROM产品JOIN产品销售ON产品.产品编号=产品销售.产品编号第六讲高级查询自身连接查询连接操作不仅可以在两个不同的表之间进行,也可以是一个表与自身进行的连接,称为表的自身连接查询。使用自身连接时,必须为表指定两个别名。例:查询选修了两门或两门以上课程的学生学号和课程号。代码如下:USESTUDENTGOSELECTa.学号,a.课程号FROM课程注册ASaJOIN课程注册ASbONa.学号=b.学号ANDa.课程号!=b.课程号GO第六讲高级查询自身连接查询结果:第六讲高级查询外连接查询在通常的连接操作中,只有满足条件的记录才能在结果集里输出。如前边的例子,产品‘0002’‘键盘’及产品‘0004’‘鼠标’没有在结果集里出现,因为这些产品没有在产品销售表中出现,也就是没有产品编号为‘0002’和‘0004’’的销售记录。但是,用户有时想以产品表为主体列出产品的销售情况,若某个产品没有销售量,则只输出产品的基信息,其销售量为空值即可。这时就需要外连接。外连接有分为左外连接、右外连接、全外连接三种。外连接除产生内连接生成的结果集外,还可以使一个表(左、右外连接)或两个表(全外连接)中的不满足连接条件的记录也出现在结果集中。第六讲高级查询外连接查询1、左外连接左外连接就是将左表作为主表,主表中所有记录分别与右表的每一条记录进行连接组合,结果集中除了满足连接条件的记录外,还有主表中不满足连接条件的记录并在右表的相应列上填充NULL值。左外连接的语法:SELECT列名列表FROM表名1LEFT[OUTER]JOIN表名2ON表名1.列名=表名2.列名第六讲高级查询外连接查询例:将产品表左外连接产品销售表。代码如下:SELECT*FROM产品LEFTOUTERJOIN产品销售ON产品.产品编号=产品销售.产品编号结果:第六讲高级查询外连接查询2、右外连接右外连接就是将右表作为主表,主表中所有记录分别与左表的每一条记录进行连接组合,结果集中除了满足连接条件的记录外,还有主表中不满足连接条件的记录并在左表的相应列上填充NULL值。右外连接的语法如下:SELECT列名列表FROM表名1RIGHT[OUTER]JOIN表名2ON表名1.列名=表名2.列名第六讲高级查询外连接查询例:将产品表右外连接产品销售表。代码如下:SELECT*FROM产品RIGHTOUTERJOIN产品销售ON产品.产品编号=产品销售.产品编号GO结果:第六讲高级查询外连接查询3、全外连接全外连接就是将左表所有记录分别与右表的每一条记录进行连接组合,结果集中除了满足连接条件的记录外,还有左、右表中不满足连接条件的记录并在左、右表的相应列上填充NULL值。全外连接的语法如下:SELECT列名列表FROM表名1FULL[OUTER]JOIN表名2ON表名1.列名=表名2.列名第六讲高级查询外连接查询例:用全连接的方法连接产品表与产品销售表。代码如下:SELECT*FROM产品FULLOUTERJOIN产品销售ON产品.产品编号=产品销售.产品编号GO结果:第六讲高级查询复合连接条件查询在上面讲述的各个连接查询中,ON连接条件表达式只有一个条件,ON连接表达式中可以有多个连接条件,称为复合连接条件。连接操作除了可以是两个表的连接,一个表与其自身的连接外,还可以是两个以上的表进行连接,我们称之为多表连接。在多表连接的过程当中,使用合法正确的连接条件,称之为复合连接条件查询。第六讲高级查询复合连接条件查询例:查询成绩在75分以上的学生的学号、姓名,选修课的课程号、课程名、专业代码、成绩,任课教师的教师编号、姓名。代码如下:SELECTB.课程号,C.教师编号,C.姓名,A.学号,A.姓名,B.专业代码,B.专业学级,B.学期,B.成绩FROM学生ASAJOIN课程注册ASBONA.学号=B.学号ANDB.成绩75JOIN教师ASCONB.教师编号=C.教师编号GO第六讲高级查询子查询子查询又称为嵌套查询即将一个查询块嵌套在另一个查询块的WHERE子句或HAVING子句的条件中,这样的查询语句称为子查询。例:父查询子查询SELECT姓名FROM学生WHERE学号IN(SELECT学号FROM课程注册WHERE课程号=’0002’)查询选修了‘0002’号课程的学生的学生姓名子查询可以嵌套在外部SELECT、INSERT、UPDATE或DELETE语句的WHERE或HAVING子句内,或者其它子查询中。第六讲高级查询子查询1、带有IN运算符的子查询在带有IN运算符的子查询中,子查询的结果是一个结果集。父查询通过IN运算符将父查询中的一个表达式与子查询结果集中的每一个值进行比较,如果相等,父查询中的查询条件表达式返回TRUE,否则返回FALSE。NOTIN运算符与IN运算符结果相反。第六讲高级查询子查询1、带有IN运算符的子查询例:使用产品和产品销售两个表,查询有产品销售记录的产品信息。查询代码如下:USESTUDENTGOSELECT*FROM产品子查询WHERE产品编号IN(SELECT产品编号FROM产品销售)第六讲高级查询子查询2、带有比较运算符的子查询在带有比较运算符的子查询中,子查询的结果是一个单值。父查询通过比较运算符将“父查询”中的表达式与子查询结果(单值)进行比较,如果相等运算的结果为TRUE,否则返回FALSE。常用的比较运算符有:,=,,=,=,,!=,!,!。第六讲高级查询子查询2、带有比较运算符的子查询例:列出高于平均分的学生的信息。代码如下:SELECT*FROM学生WHERE学号IN(SELECT学号FROM课程注册WHERE成绩(SELECTAVG(成绩)FROM课程注册))第六讲高级查询子查询3、带有ANY或ALL运算符的子查询使用ANY或ALL运算符时,必须同时使用比较运算符。在带有ANY或ALL运算符的子查询中,子查询的结果是一个结果集。父查询通过ANY(或ALL)运算符将“父查询”中的一个表达式与子查询结果集中的每一个值进行比较,如果相等运算后结果为TRUE,否则返回FALSE。第六讲高级查询子查询3、带有ANY或ALL运算符的子查询例:查询比‘010101001’班中某一学生年龄小的其它班的学生学号与姓名。SELECT学号,姓名FROM学生WHERE出生日期ANY(SELECT出生日期FROM学生WHERE班级代码='010101001')AND班级代码'010101001'GO第六讲高级查询子查询4、带有EXISTS运算符的子查询在带有EXISTS运算符的子查询中,子查询不返回任何数据,只产生逻辑真值TRUE或逻辑假值FALSE.。第六讲高级查询子查询4、带有EXISTS运算符的子查询例:查询所有选修了“0001”课程的学生姓名。查询代码如下:USESTUDENTGOSELECT学号,姓名FROM学生WHEREEXISTS(SELECT*FROM课程注册WHERE学号=学生.学号AND课程号='0001')GO第六讲高级查询子查询4、带有EXISTS运算符的子查询由于EXISTS引出的子查询其目标列通常为*,因为带有EXISTS的子查询只返回逻辑值,给出列名没有实际意义。相关子查询--这类子查询与前面讲的子查询有不同之处,即子查询的条件依赖于父查询的某一个属性值。不相关子查询--子查询依赖于父查询学生表中的学号属性值。而子查询的查询条件不依赖于父查询的属性值。不相关子查询是一次求解,而相关子查询的求解与不相关的子查询不同,它的过程是:首先取外层查询表(学生表)的第一个记录,拿这个记录与内层查询相关的属性值(学号值)去参与内层查询的求解,若内层查询的WHERE子句返回真值,则将这个记录放入结果集;然后再取外层查询表(学生表)的下一条记录;重复上述过程,直到外层表(学生表)全部处理完为止。