一章写不完啊,这里全是概念和实战,所以再来一章,希望这章可以学的好一点
掌握连接查询
连接查询
连接查询:同时涉及多个表的查询。用来连接两个表的条件称为连接条件或连接谓词 。
连接条件的一般格式:
[<表名1>]<列名1> <比较运算符> [<表名2>]<列名2>
或 [<表名1>]<列名1> BETWEEN [<表名2>]<列名2> AND [<表名2>]<列名3>
其中:连接谓词中的列名称为连接字段,连接条件中的各连接字段类型必须是可比的,但不必是相同的。
嵌套循环法
首先在表1中找到第一个元组,然后从头开始扫描表2,逐一查找满足连接件的元组,找到后就将表1中的第一个元组与该元组拼接起来,形成结果表中一个元组。
表2全部查找完后,再找表1中第二个元组,然后再从头开始扫描表2,逐一查找满足连接条件的元组,找到后就将表1中的第二个元组与该元组拼接起来,形成结果表中一个元组。
重复上述操作,直到表1中的全部元组都处理完毕 。
排序合并法
首先按连接属性对表1和表2排序。
对表1的第一个元组,从头开始扫描表2,顺序查找满足连接条件的元组,找到后就将表1中的第一个元组与该元组拼接起来,形成结果表中一个元组。当遇到表2中第一条大于表1连接字段值的元组时,对表2的查询不再继续。
找到表1的第二条元组,然后从刚才的中断点处继续顺序扫描表2,查找满足连接条件的元组,找到后就将表1中的第一个元组与该元组拼接起来,形成结果表中一个元组。直接遇到表2中大于表1连接字段值的元组时,对表2的查询不再继续。
重复上述操作,直到表1或表2中的全部元组都处理完毕为止 。
索引连接
对表2按连接字段建立索引。
对表1中的每个元组,依次根据其连接字段值查询表2的索引,从中找到满足条件的元组,找到后就将表1中的第一个元组与该元组拼接起来,形成结果表中一个元组。
SQL中连接查询的主要类型:广义笛卡尔积查询、等值连接(含自然连接)查询、非等值连接查询、自身连接查询、外连接查询、复合条件连接查询。
广义笛卡尔积(很少使用):不带连接谓词的连接。
SELECT Student.* , SC.* FROM SStudent, SC;
等值连接:连接运算符为 = 的连接操作。
格式:[<表名1>.]<列名1> = [<表名2>.]<列名2>
说明:任何子句中引用表1和表2中同名属性时,都必须加表名前缀。引用唯一属性名时可以加也可以省略表名前缀。
查询每个学生及其选修课程的情况
SELECT SStudent.*,SC.* FROM SStudent,SC
WHERE SStudent.Sno = SC.Sno;
自然连接:等值连接的一种特殊情况,把目标列中重复的属性列去掉。
查询每个学生及其选修课程的情况
SELECT SStudent.Sno,Sname,Ssex,Sage, Sdept,Cno,Grade
FROM SStudent,SC WHERE sStudent.Sno = SC.Sno;
非等值连接查询:连接运算符不是 = 的连接操作。
自身连接:一个表与其自己进行连接。连接需给表起别名以示区别,由于所有属性名都是同名属性,因此须使用别名前缀。
查询每一门课的间接先修课(即先修课的先修课)。
SELECT FIRST.Cno,SECOND.Cpno
FROM SCourse FIRST,SCourse SECOND
WHERE FIRST.Cpno = SECOND.Cno;
外连接分为左外连接(LEFT OUTER JOIN或LEFT JOIN)、右外连接(RIGHT OUTER JOIN或RIGHT JOIN) 和全外连接(FULL OUTER JOIN或FULL JOIN)三种。与内连接不同的是,外连接不只列出与连接条件相匹 配的行,而是列出左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的数据行
复合条件连接:WHERE子句中含多个连接条件
查询选修2号课程且成绩在90分以上所有学生的学号、姓名。
SELECT Student.Sno, student.Sname FROM Student, SC
WHERE Student.Sno = SC.Sno AND SC.Cno= ' 2 ' AND SC.Grade > 90;
查询每个学生的学号、姓名、选修的课程名及成绩。
SELECT SStudent.Sno,Sname,Cname,Grade
FROM SStudent,SC,SCourse
WHERE SStudent.Sno = SC.Sno and SC.Cno = SCourse.Cno;
嵌套查询
概述:一个SELECT-FROM-WHERE语句称为一个查询块,将一个查询块嵌套在另一个查询块的WHERE子句或HAVING短语的条件中的查询称为嵌套查询。其中外层查询块称为父查询,内层查询块称为子查询,子查询不能使用ORDER BY子句。层层嵌套方式反映了 SQL语言的结构化,有些嵌套查询可以用连接运算来替代。
SELECT Sname FROM Student 外层查询/父查询
WHERE Sno IN
(SELECT Sno FROM SC 内层查询/子查询
WHERE Cno= ' 2 ');
嵌套查询分类
不相关子查询:子查询的查询条件不依赖于父查询,由里向外逐层处理。即每个子查询在上一级查询处理之前求解,子查询的结果用于建立其父查询的查找条件。
相关子查询:子查询的查询条件依赖于父查询,首先取外层查询中表的第一个元组,根据它与内层查询相关的属性值处理内层查询,若WHERE子句返回值为真,则取此元组放入结果表;然后再取外层表的下一个元组。重复这一过程,直至外层表全部检查完为止。
引出子查询的谓词:带有IN谓词的子查询、带有比较运算符的子查询、带有ANY或ALL谓词的子查询、带有EXISTS谓词的子查询。
带有IN谓词的子查询
- 查询与刘晨在同一个系学习的学生。### 集合查询
- 确定刘晨所在系名。
SELECT Sdept FROM Student WHERE Sname= ‘ 刘晨 ’;- 查找所有在IS系学习的学生。
SELECT Sno,Sname,Sdept FROM Student WHERE Sdept= ’ IS ';- 上例可构造嵌套查询:将第一步查询嵌入到第二步查询条件中。 SELECT Sno,Sname,Sdept FROM SStudent WHERE Sdept IN
(SELECT Sdept FROM SStudent WHERE Sname=‘刘晨’);- 此查询为不相关子查询,DBMS求解该查询时也是分步去做的。
也可用自身连接完成本查询要求:
SELECT S1.Sno,S1.Sname,S1.Sdept FROM SStudent S1,SStudent S2
WHERE S1.Sdept = S2.Sdept AND S2.Sname =‘刘晨’;- 父查询和子查询中的表均可以定义别名:
SELECT Sno,Sname,Sdept FROM SStudent S1 WHERE S1.Sdept IN
(SELECT Sdept FROM SStudent S2 WHERE S2.Sname= ‘刘晨’);
带有比较运算符的子查询:当能确切知道内层查询返回单值时,可用比较运算符(>,<,=,>=,<=,!=或< >)。
- 假设一个学生只可能在一个系学习,并且必须属于一个系,则可以用 = 代替IN :
SELECT Sno,Sname,Sdept FROM Student WHERE Sdept=
SELECT Sdept FROM Student WHERE Sname=‘ 刘晨 ’;
- 子查询一定要跟在比较符之后,一个错误的例子如下:
SELECT Sno,Sname,Sdept FROM Student
WHERE ( SELECT Sdept FROM Student
WHERE Sname= ‘ 刘晨 ’ ) = Sdept;
带有ANY或ALL谓词的子查询:谓词ANY表示任意一个值,ALL表示所有值,但需要配合使用比较运算符。
(>=) ANY 大于(大于等于)子查询结果中的某个值
(>= )ALL 大于(大于等于)子查询结果中的所有值
< (<= ) ANY 小于(小于等于)子查询结果中的某个值
< (<= ) ALL 小于(小于等于)子查询结果中的所有值
= ANY 等于子查询结果中的某个值
=ALL 等于子查询结果中的所有值(通常没有实际意义)
!=ANY 不等于子查询结果中的某个值
!=ALL 不等于子查询结果中的任何一个值
查询其他系中比信息系任意一个(其中某一个)学生年龄小的学生姓名和年龄。
SELECT Sname,Sage FROM SStudent
WHERE Sage < ANY (SELECT Sage FROM SStudent
WHERE Sdept='IS')
AND Sdept <>'IS';
/* 注意这是父查询块中的条件 */
结果: Sname Sage
王敏 18
执行过程:
1.DBMS执行此查询时,首先处理子查询,找出 IS系中所有学生的年龄,构成一个集合(19,18)。
2. 处理父查询,找所有不是IS系且年龄小于19 或 18的学生。
用集函数实现子查询通常比直接用ANY或ALL查询效率要高,
因为前者通常能够减少比较次数。
用集函数实现例39如下:
SELECT Sname,Sage FROM Student
WHERE Sage < (SELECT MAX(Sage) FROM Student
WHERE Sdept= ’ IS ') AND Sdept <> ’ IS ’;
查询其他系中比IS系所有学生年龄都小的学生姓名及年龄。
用ALL谓词
SELECT Sname,Sage FROM Student WHERE Sage < ALL
(SELECT Sage FROM Student WHERE Sdept= ' IS ')
AND Sdept <> ' IS ’;
用集函数
SELECT Sname,Sage FROM Student WHERE Sage <
(SELECT MIN(Sage) FROM Student WHERE Sdept= ' IS ')
AND Sdept <>' IS ’;
带有EXISTS谓词的子查询
[NOT]EXISTS谓词:相当于存在量词 。带有EXISTS谓词的子查询不返回任何数据,只产生逻辑true或false,若内层查询结果非空则返回真值,否则返回假值。由EXISTS引出的子查询的目标列表达式通常都用* ,因为带EXISTS的子查询只返回真值或假值,给出列名无实际意义。
掌握集合查询
集合查询:标准SQL直接支持并操作,而一般商用数据库支持并操作、交操作和差操作。
并操作(UNION):参加UNION操作的各结果表的列数必须相同;对应项的数据类型也必须相同。一般格式为:
<查询块>
UNION
<查询块>
查询计算机系的学生及年龄不大于19岁的学生。
SELECT * FROM Student WHERE Sdept= 'CS'
UNION
SELECT * FROM Student WHERE Sage<=19;
SELECT DISTINCT * FROM Student
WHERE Sdept= 'CS' OR Sage<=19;
查询选修了课程1或者选修了课程2的学生。
SELECT Sno FROM SC WHERE Cno=' 1 '
UNION
SELECT Sno FROM SC WHERE Cno= ' 2 ';
SELECT DISTINCT Sno FROM SC
WHERE Cno=' 1 ' OR Cno= ' 2 ';
设数据库中有一教师表Teacher(Tno, Tname,…)。查询学校中所有师生的姓名。
SELECT Sname FROM Student
UNION
SELECT Tname FROM Teacher;
交操作(INTERSECT):标准SQL中没有提供集合交操作,但可用其他方法间接实现。
查询计算机系的学生与年龄不大于19岁的学生的交集(实际上就是查询计算机系中年龄不大于19岁的学生)。
SELECT * FROM Student WHERE Sdept= 'CS' AND Sage<=19;
查询选修课程1的学生集合与选修课程2的学生集合的交集(实际上就是查询既选修了课程1又选修了课程2的学生)。
SELECT Sno FROM SC WHERE Cno=' 1 ' AND Sno IN
(SELECT Sno FROM SC WHERE Cno=' 2 ');
差操作(MINUS):标准SQL中没有提供集合差操作,但可用其他方法间接实现。
查询计算机科学系的学生与年龄不大于19岁的学生的差集(实际上就是查询计算机科学系中年龄大于19岁的学生)。
SELECT * FROM Student WHERE Sdept= 'CS' AND Sage>19;
对集合操作结果的排序: ORDER BY子句用数字指定排序属性,只用于对最终查询结果排序,不能对中间结果排序。任何情况下,ORDER BY子句只能出现在最后。
错误写法:
SELECT * FROM Student WHERE Sdept= 'CS' ORDER BY Sno
UNION
SELECT * FROM Student WHERE Sage<=19 ORDER BY Sno;
正确写法:
SELECT * FROM Student WHERE Sdept= 'CS'
UNION
SELECT * FROM Student WHERE Sage<=19 ORDER BY 1;
理解SELECT语句的一般格式
查询年龄最大的三个学生的姓名、年龄及所在的系
Select TOP 3 sname,sdept from student order by sage desc
如果包括并列的第三名的学生。则为。
Select TOP 3 with ties sname,sdept from student order by sage desc
用了with ties 需要order by
不用order得到的结果可能与希望的不同。
查询VB课程考试成绩前三名的学生的姓名和成绩
Select TOP 3 with ties sname,grade from student s join sc on s.sno=sc.sno join course c on c.cno=sc.cno where cname=‘VB’ order by grade DESC
语法格式:
Select 查询表序列 into 新表名
from 数据源 where [<条件>]……
新表有二类:1)永久的表,起一个表名就可以了;
2)局部临时表:表名前加#,当前连接可用,生存期为当前连接的生存期.
全局临时表:表名前加##,所有连接都可用.生存期为当前连接的生存期
将计算机系的学生信息存入#computer局部临时表中。
select sno,sname,ssex,sage into #computer from student where sdept=‘计算机系’
将修了VB课程的学生的学号及成绩存入全局临时表##VB中
Select sno,grade into ##VB from sc join course c on c.cno=sc.cno where cname=‘VB’
将计算机系学生的姓名、修课的课程名和成绩存入永久表S_C_G中
Select sname,cname,grade into S_C_G from student s join sc on s.sno=sc.sno join course on c.cno=sc.cno where sdept=‘计算机系’
在已经存在的表中插入数据文章来源:https://www.toymoban.com/news/detail-406047.html
insert into sc1 select * from sc;
查询001号课程的学号和成绩,并进行如下处理成绩>90 显示优。80-89:良文章来源地址https://www.toymoban.com/news/detail-406047.html
Select sno,
CASE
WHEN GRADE>=90 THEN ‘优’
WHEN GRADE BETWEEN 80 AND 89 THEN ‘良’
WHEN GRADE BETWEEN 70 AND 79 THEN ‘中’
WHEN GRADE BETWEEN 60 AND 69 THEN ‘及格’
WHEN GRADE<60 THEN ‘不及格’
End as degree
From sc
Where cno=‘001’ and grade is not null
Select
CASE
WHEN degree>=90 THEN '优'
WHEN degree BETWEEN 80 AND 89 THEN '优'
WHEN degree BETWEEN 70 AND 79 THEN '良'
WHEN degree BETWEEN 60 AND 69 THEN '及格'
WHEN degree<60 THEN '不及格'
End as grade
From score
Where degree is not null group by degree
Use pubs;
Select category=
case type
when 'popular_comp' then '流行计算类'
when 'mod_cook' then '现代烹饪类'
when 'business' then '商业类'
when 'psychology' then '心理学类'
when 'trad_cook' then '传统烹饪类'
Else '未分类'
End,
Title,price from titles where price is not null order by type,price
SELECT语句的一般格式
SELECT [ALL|DISTINCT] <目标列表达式> [别名] [,<目标列表达式> [别名]] …
FROM <表名或视图名> [别名] [ ,<表名或视图名> [别名]] …
[WHERE <条件表达式>]
[GROUP BY <列名1>[,<列名1’>] ...
[HAVING <条件表达式>]]
[ORDER BY <列名2>[ASC|DESC] [,<列名2’> [ASC|DESC]] ]
到了这里,关于数据库:关系数据库标准语言(二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!