文章目录
第四章:SQL语言及其操作
一:SQL语言的特点
- 功能一体化:三个子语言构成
- 语言非过程化
- 交互式和嵌入式使用
- 标准化淤易移植性
- 简单易学
二:数据库定义子语言及其操作
2.1:DDL的操作
- 数据库的建立、删除、修改
- 数据库日志的建立、删除、修改
- 数据库表的建立、删除、修改
- 视图的建立、删除、修改
- 索引的建立、删除
- 规则的建立、删除
- 触发器的建立、修改、删除
- 默认值的建立、删除
- 函数Function的建立、修改、删除
2.2:定义子语言的关键字及语法
- create
- drop
- alter
- SQL SERVER中INDEX,RULE,DEFAULT没有ALTER命令
- 默认值实例:设定一个全局缺省值,可多次赋值
create default dft_term as ‘1’
sp_bindefault dft_term,’ctake.term’
sp_unbindefault ‘ctake.term’
drop default dft_term
- 规则实例:设定一个规则,可以将规则绑定到列
create rule mark_rule as @mark between 0 and 100
sp_bindrule mark_rule,’Ctake.mark’
sp_unbindrule ‘Ctake.mark’
drop rule mark_rule
2.3:定义数据库及日志
- 数据库:是一个存储空间。用于存放相关数据集合,包括表、视图、索引、存储过程、触发器、与数据库安全性有关的控制机制以及其它对象等。
- 日志(Log):是数据库故障恢复的重要手段和方法。用于记录对数据库的各种操作及所涉及的相关数据,实际上也需要一个存储空间。为安全起见,一般与数据库分开存放。
- 创建:
--创建
Create Database StudnetData
On Primary
( Name = StudentFile1, --主文件
Filename = 'c:\data\StuFile1.mdf', --主数据文件扩展名
Size = 10MB,
MaxSize = 1000MB,
FileGrowth = 5MB),
( Name = StudentFile2, --次文件
Filename = 'c:\data\StuFile2.ndf', --次文件扩展名
Size = 10MB,
MaxSize = 1000MB,
FileGrowth = 5MB)
Log On
( Name = Studentlog, --日志文件
Filename = 'c:\data\Stulog.ldf', --日志文件扩展名
Size = 10MB,
MaxSize = 1000MB,
FileGrowth = 5MB)
- 修改:可使用alter修改数据库,增加性的数据或日志文件,删除已有文件,修改文件的设置
-- 增加数据文件
ALTER Database StudentData
ADD File
(Name = StudentFile3,
Filename ='c:\data\StuFile3.ndf',
Size = 10MB,
MaxSize = 1000MB,
FileGrowth = 5MB)
-- 修改数据文件
ALTER Database StuData
MODIFY FILE
(Name = StudentFile1,
MaxSize = 3000MB)
- 删除:drop database 数据库名
2.4:定义数据表
- 表创建
--表创建
CREATE TABLE student
( SID char(8) primary key,
SName nvarchar(12),
SBirthyear smalldatetime,
SGender char(1) check(Sgender in ('f','m')),
SPhone char(11) check(SPhone like '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'),
SAge as datepart(yyyy,getdate())-datepart(yyyy, SBirthyear) )
--数据插入
insert student values('20130301','王磊','1992-03-05','m','13809021031')
insert student values('20130304','赵刚','1994-10-05','m','13981922204')
- 表修改
--原表
CREATE TABLE department
( depname varchar(20) PRIMARY KEY,
adress varchar(40) NOT NULL,
telephone char(11) constraint tele_check check(telephone like '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'))
--增加“主任”的属性
alter table department
add director varchar(10)
--修改关系的地址属性
Alter table department
alter column adress varchar(50)
--为系关系删除tele_check检查
alter table department
drop constraint tele_check
--为telephone列添加约束
alter table department
add constraint tele_check check(telephone like '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]')
- 表修改注意事项
- 不能修改计算的列、约束、默认值或者索引中引用的列。
- 不能对已有空值的列设为NOT NULL.
- 新增加的列不能定义为“NOT NULL”。因为基本表在增加一列后,原有元组在增加的列上的值都被定义为空值。
- 表的删除:drop table 表名
2.5:定义视图
- 视图:视图是一种数据库对象,它由多个字段列和数据行构成,这些列和行来自于一个或多个物理数据表。视图是一个虚拟表,所对应的数据是存储在所引用的数据表中,被引用的表称为基表。
- 视图的特点:
- 视图是由基表(实表)产生的表(虚表),视图的列可以来自不同的表。
- 视图的建立修改不影响基表
- 对视图内容的更新(添加、删除和修改)直接影响基表。
当视图来自多个基表时,不允许添加和修改数据。
- 视图的创建
--多源表视图
CREATE VIEW V_IS_S1(Sno,Sname,Grade) AS
SELECT Student.Sno,Sname,Grade FROM Student JOIN SC
ON Student.Sno=SC.Sno WHERE Sdept=‘信息管理系’ AND SC.Cno=‘C001’
--在已有视图上定义新的视图
CREATE VIEW IS_Student_Sage AS
SELECT Sno,Sname,Sage FROM IS_Student WHERE Sage<20
--定义带表达式的视图
CREATE VIEW BT_S (Sno,Sname,Sbirth) AS
SELECT Sno,Sname,datepart(yyyy,getdate()-Sage FROM Student
- 视图创建的注意事项
- 只能在当前数据库中创建视图
- 不能将规则或default定义与视图相关联
- 在某些情况下视图创建者必须为视图中的列重新命名
- 删除视图:drop view StuCourse
- 利用系统存储过程查看视图信息
sp_help显示数据库对象的特征
sp_helptext查看数据库对象在系统表中的定义
sp_depends显示有关数据库对象相关性的信息
2.6:定义索引
- 索引的概念:索引是关于数据位置信息的关键字表
- 索引的目的:快速在磁盘上定位所需数据,加快查询速度。
- 索引的类型:聚簇(Clustered)索引、非聚簇(Nonclustered)索引和唯一(Unique)索引。
- 聚簇索引:给某列或多个(组合)列建索引时,重组磁盘上的表的数据,使得表的数据按照索引的顺序存储,表中数据与索引存储在相邻物理空间。每张表最多只能建一个聚簇索引。
- 非聚簇索引:不要求表数据的物理存储顺序与索引顺序保持一致
- 唯一索引:被索引的列不能有相同值出现。可用来限定聚簇索引和非聚簇索引。
- 索引的创建:create index 命令语法
--按学号降序排列:系统默认是升序
CREATE INDEX StuGraIDx
ON SC (Sid) DESC
- 索引的删除:drop index
drop index StuGraIDx
- 索引建立的原则:
- 为数据量大的表建立索引,这样速度提高明显;
- 一张表所建索引个数应适量,要在加快查询速度和降低更新速度之间平衡。
- 掌握建立索引的时机,通常在表装载完成之后,再建立索引。
- 优先建立主键列的索引
2.7:触发器的创建和修改
- 触发器的概念:数据库触发器是存储在数据库中、根据发生的事件而自动触发执行的一种存储子程序。触发器是由一个事件来启动运行,即触发器是当某个事件发生时自动地隐式运行。
- 触发器的用途:
- 触发器可通过数据库中相关表实现级联更改,实现多个表之间数据的一致性和完整性。
- 触发器可以强制比用CHECK约束定义的约束更为复杂的约束。与CHECK约束不同,触发器可以引用其它表的中列。
- 触发器也可以评估数据修改前后的表状态,并根据其差异采取对策。
- 触发器触发时:
- 系统自动在内存中创建Deleted表和inserted表,这两张表是逻辑表,不是存储在数据库中,而是存储在内存中
- 并且这两张表是由系统管理的,是只读,不允许修改;触发器执行完成后,自动删除。用户不能向这两张表中写入内容。
- 触发器的创建:
--语法
create trigger trigger_name
on table_name
[with encryption]--表示加密触发器定义的SQL文本
for[delete,insert,update]--触发器类型
as
T-sql
go
--实例1:用触发器实现表间外键数据的完整性
use student
go
if exists(select name from sysobjects
where name=‘del_banji’ and type=‘TR’)
drop trigger del_banji
go
create trigger del_banji on 班级
for delete
as
declare @banjidaima char(9) --定义用户变量
select @banjidaima=班级代码 from deleted --用户变量赋值
if exists(select *from 学生 where 班级代码=@banjidama)--用户变量比较
begin
print ’班级正在使用,不能删除’
rollback transaction
end
go
--实例2: 用触发器实现表间业务数据一致性
create trigger trig_transinfo
on transinfo
for insert
as
declare @type char(4),@outMoney MONEY
declare @myCardID char(10),@balance MONEY
select @type=transType,@outMoney=transMoney,
@myCardID=cardID from inserted
if(@type=‘支取’)
update bank set currentMoney=currentMoney-@outMoney
where cardID=@myCardID
else
update bank set currentMoney=currentMoney+@outMoney
where cardID=@mycrdID
go
--实例3:用触发器实现业务数据的备份
create trigger trig_delete_transinfo
on transinfo
for delete
as
print’开始备份数据,请稍后’
if not exists(select *from sysobjects where name=‘backupTabble’)
select * into backupTable from deleted
else
insert into backTable select *from selected
print’备份数据成功,备份中的数据为:’
select * from backupTable
go
--实例4:用触发器实现数据的动态性校验
create trigger trig_update_bank
on bank
for update
as
declare @beforeMoney MONEY,@afterMoney MONEY
select @beforeMoney=currentMoney from deleted
select @afterMoney=currentMoney from inserted
if ABS(@afterMoney-@beforeMoney)>20000
begin
print’交易金额’+convert(varchar(8),ABS(@afterMoney-@beforeMoney))
raiserror (‘每笔交易不能超过2万元,交易失败’,16,1)
rollback transaction
end
go
- 触发器的启动:alter table 表名 enable
- 触发器的禁用:alter table 表名 disable
- 触发器的删除:drop trigger 触发器名
三:数据库操纵子语言及其操作
3.1:DML
- DML的四个命令关键字:插入insert,修改update,删除delete,查询select
3.2:数据插入insert
- 插入一行:insert [into] 表名或视图名 [(属性名序列)] values (一行中各列的值)
CREATE TABLE T
(Tid int identity(1,1) PRIMARY KEY,
Tname CHAR(8) NOT NULL,
TITLE CHAR(10))
INSERT INTO T VALUES (5,'WANG','Lecturer')
INSERT INTO T VALUES ('Zhang','Lecturer')
INSERT INTO T(Tname) VALUES('LI')
INSERT INTO T(TITLE) VALUES('PROFESSOR')
- 插入多行:INSERT [INTO] 表名或视图名 [(属性名序列)] SELECT子句
--把一个select语句的查询结果插入到表中
Create table SC1
( Sid Char(10),
Cid varchar(10),
score smallint )
INSERT SC1 SELECT Sid,Cid,Score FROM SC WHERE Score >= 85
/*
INSERT [INTO] 表名或视图名 [(属性名序列)]
SELECT 属性值列表 UNION SELECT 属性值列表
*/
insert t(tname,title)
select 'Zhang','Lecturer' Union
select 'WANG','Lecturer' Union
select 'LI','Lecturer'
3.3:数据修改update
- 简单数据更新中的例子里,表中的所有元组对应的属性值都更改成为新值。
- 简单的更新:
UPDATE publishers SET city = 'Atlanta', state ='GA'
UPDATE SC SET Score = Score + 10
- 带where子句的更新:表中符合条件的所有元组对应的属性值都改成新值
UPDATE authors SET state = 'PC', city = 'Bay City'
WHERE state = 'CA' AND city = 'Oakland'
- 利用select查询子句的结果进行数据修改
/*
学生表 S(Sid,Sname, Age,Gender)
选课表 SC(Sid, Cid, Score)
*/
--把女同学的成绩提高10%
UPDATE SC SET Score = Score * (1+10%)
WHERE SC.Sid IN(SELECT Sid FROM S WHERE GENDER='F')
3.4:数据的删除delete
- 单表数据删除
--把课程名为maths的选课记录从SC中删除
delete from SC
where Cid in (select Cid from C where Cname=‘Maths’)
--把选了C4课程,但小于该课程平均成绩的元组从基本表SC中删除
delete from SC
where Cid=‘C4’ and score<(select avg(score) from SC where Cid=‘C4’)
- 多表联接删除
--从选课表中删除学生“李舢”的记录。
delete SC from SC,S
where SC.sid=S.sid and Sname=‘李舢’
--或者
delete from SC
where sid in (select sid from S where Sname=‘李舢’)
3.5:数据查询select
- 说明:查询主要由一些子句构成,如:SELECT子句、INTO子句(Clause)、FROM子句、WHERE子句、GROUP BY子句、HAVING子句、ORDER BY子句、COMPUTE子句等。
- select子句
--语法
SELECT [ ALL | DISTINCT ] < select_list >
< select_list > ::=
{ * | { 表名 | 视图名 | 表别名 }.* | { 列名 | 表达式} [ [ AS ] 列别名 ] | 列别名 = 表达式 } [ ,...n ]
/*
1)ALL表示重复行可出现于结果中,DISTINCT则相反,ALL为缺省情况;
2) * 表示FROM子句的表、视图中的所有列均出现于结果中,其顺序遵照表、视图中的顺序。
3)表达式中可用聚集函数。
*/
--在SC中检索女同学选修的课程号
select distinct cid --因为一门课程可以有许多女同学选修,因此为避免输出
from Student S,SC where S.sid=SC.sid and Ssex=‘女’
--在SC、S和C表中检索数据库原理与设计课程成绩超过80分的学生的学号、姓名和成绩
select S.Sid,Sname,Score
from Student S,SC,Course C where S.sid=SC.sid and SC.cid=C.cid and Cname=‘数据库原理与设计’ and score>80
--查询“c001”课程比“c002”课程成绩高的所有学生的学号;
select s.sno as 学号 from sc c,sc s where c.sno=s.sno and
c.cno= 'c001' and s.cno = 'c002' and c.score>s.score
--或者
select s.sno as 学号 from
(Select * from sc where sc.cno= 'c001') as S,
(Select * from sc where sc.cno= 'c002') as C
where S.score>C.score and S.sno=C.Sno
--查询选修了“吕燕”老师课程成绩不及格的同学的学号和课程
select s.sno as 学号,SC.CNo as 课程号 from sc,course C,
teacher T where sc.cno=C.cno and C.tno=T.tno and
tname='吕燕' and score<60
--或者
select sno as 学号,cno as 课程号 from sc where score<60 and
cno in (select cno from course where tno in (select tno from teacher where tname='吕燕') )
- into子句:into 新表名;创建一新表并将查询结果数据插入其中
(1) SELECT……INTO不能与COMPUTE一起使用;
(2)可用SELECT……INTO创建一张与FROM子句中的表具有相同结构的、属性名相(不)同的新表。如果不需要数据,可令WHERE子句条件为永假即可
- from子句:from 表名
- from的作用:指定在SELECT、DELETE及UPDATE语句中所用的表、视图及表连接等
- where子句作用:指定限定行的查询条件
算术比较符:=、<、>、<=或!>、>=或!<、<>或!=
逻辑比较符:AND、OR、NOT
特殊运算符:IN、NOT IN、BETWEEN…AND…、LIKE、NOT LIKE、IS NULL、IS NOT NULL、SOME|ANY、ALL、EXISTS、NOT EXISTS。
- like:用于模糊匹配
- LIKE之后的表达式(模式)中使用
–%(匹配任意一串字符)
–_(匹配任意一个字符)
–[ ](取其中任意单个字符)
–^(非)- 如希望%、_以常规字符出现,则应用[ ]将其括起或用转义符“ ” , 如 : l i k e ‘ 70 ”,如:like ‘70 ”,如:like‘70%’ 或 like ‘70[%]’=> 70%
- ^应与[ ]联用,如:[a-f]或[abcdef]表示a-f这几个字母不能出现。
- ‘Iam%[a-h]_[Q-T]%’匹配的是: IamGoodinEnglish
--模糊查询那些书名中包含“网络”两个字的图书
SELECT *
FROM Book
WHERE title LIKE '%网络%'
- 特殊运算法:[NOT] EXISTS (子查询)
- 含意:检查子查询是否有结果(行)返回,有则TRUE,否则FALSE;如带NOT则相反。
/*
有四个关系表:T(Tid, Tname,Title), C(Cid, Cname,Tid),S(Sid,Sname,Age,Gender), SC(Sid, Cid, Score)
查询学习课程号为0002课程的学生学号与姓名
*/
SELECT Sid, Sname FROM Students S
WHERE EXISTS (SELECT * FROM SC
WHERE SC.Sid = S.Sid AND
SC.Cid= '0002')
--例:查询全选了课程的学生
select * from Stu ts
where not exists (select * from Course c where not exists (select * from ctake where ctake.Sid=ts.Sid and ctake.Cid=C.Cid))--没被选的课
--例:查询没有选择所有课程的学生
select Sid,Sname from Students
where exists (select * from course where not exists (select * from SC where SC.Sid=Students.Sid and Cid=course.Cid))
3.3:聚集函数
- 聚集函数作用:用于对数据集合进行统计,如求:总和、平均值、最
大值、最小值、行数。 - 聚集函数的用法:一般用于SELECT子句、HAVING子句和ORDER BY子句中。
- 函数形式及功能
COUNT(DISTINCT|ALL 表达式) 返回非空表达式值的行数
COUNT(*) 返回结果的行数,含NULL行和重复行
MAX(DISTINCT|ALL 表达式) 非空表达式值的最大值
MIN (DISTINCT | ALL 表达式) 非空表达式值的最小值
SUM (DISTINCT | ALL 表达式) 非空表达式值的总和值
AVG (DISTINCT | ALL 表达式) 非空表达式值的平均值
- 各函数中,默认为All, 不计空行,但应计重复行。MIN、MAX、COUNT适合于任何数据类型,其余一般要求数值型。
SELECT sum(score) from SC where Sid='20110101'
SELECT Count(*) from SC where Sid='20110101'
SELECT AVG(Score) FROM SC,Course where SC.Cid=Course.Cid and Cname='数据库原理与设计'
SELECT Max(Score) FROM SC,Course where SC.Cid=Course.Cid and Cname='数据库原理与设计'
SELECT Min(Score) FROM SC,Course where SC.Cid=Course.Cid and Cname='数据库原理与设计'
3.4:group by 子句与hanving子句
GROUP BY子句作用:用于对查询的结果数据集合进行“分组”或“分组统计”,如对各个分组求:总和、平均值、最大值、最小值、行数。
GROUP BY子句用法:一般与“聚集函数”联用。
HAVING子句作用:用于对分组数据集合的再筛选。
HAVING子句用法:须与GROUP BY联用,不能单独使用。
(1)要求SELECT子句的列表中,除了使用聚集函数的列之外,其余各列都必须出现在Group By子句的列表中。即,SELECT是对GROUP BY的结果做投影。
(2) 注意WHERE、GROUP BY及HAVING三个子句的执行顺序及含意。WHERE用于对FROM子句结果设置过滤条件;GROUP BY用于对WHERE子句的结果分组;HAVING则对GROUP BY分组的结果再过滤。
--统计每门课程的学生选修人数
SELECT Course.Cid, COUNT(DISTINCT Sid) FROM
Course,ctake WHERE Course.Cid=ctake.Cid GROUP BY Course.Cid
--查询学生学号、姓名、平均分及选课门数
SELECT Students.Sid as 学号,Sname as 姓名,AVG(SCORE) as 平均成绩 ,Count(SC.Cid) as 选课门数 from Students,SC where Students.Sid=SC.Sid GROUP BY Students.Sid,Sname
--统计平均成绩85分以上的同学的平均成绩
SELECT Stu.Sid as 学号,Sname as 姓名,AVG(mark) as 平均成绩, Count(ctake.Cid) as 选课数 from Stu,ctake where Stu.Sid=Ctake.Sid GROUP BY Stu.Sid,Sname Having AVG(mark)>85
--统计选了3门及以上课程且平均成绩85分以上的同学的平均成绩
SELECT Stu.Sid as 学号,Sname as 姓名,Count(ctake.Cid), AVG(mark) as 平均成绩 from Stu,ctake where Stu.Sid=ctake.Sid GROUP BY Stu.Sid,Sname Having AVG(mark)>85 and Count(ctake.Cid)>=3
--查询每门课程的及格率、输出课程编码、名称、平均分和及格率
select C.CID 课程编码,Cname 课程名称
3.5order by,compute,compute by
ORDER BY :用于对结果集进行排序。
语法: ORDER BY { 排序表达式 [ ASC | DESC ] } [ ,…n]
说明: ORDER BY中的列一般应在SELECT子句中。
COMPUTE:COMPUTE用于对查询的结果数据集合最后进行“总计”,如果带有BY,则还可进行“小计”。
说明: COMPUTE BY应与ORDER BY联用,且COMPUTE BY后的表达式应与ORDER BY后的表达式(或其子集)内容与顺序一致。
示例:如有ORDER BY a, b, c 则可用如下任一COMPUTE BY形式: (1) COMPUTE BY a, b, c (2)COMPUTE BY a, b (3)COMPUTE BY a
SELECT Stu.Sid as 学号,Sname as 姓名,Cname as 课程名称, Score as 成绩 from Stu,ctake,Course where Stu.Sid=ctake.Sid and ctake.Cid=Course.Cid order by Cname COMPUTE Min(mark),max(mark) by Cname --按课程统计
SELECT Students.Sid as 学号,Sname as 姓名,Cname as 课程名称, Score as 成绩 from Stu,ctake,Course where Stu.Sid=ctake.Sid and ctake.Cid=Course.Cid order by Stu.Sid ,Sname COMPUTE AVG(mark),Count(Course.Cname) by Students.Sid --按学生统计
--查询所有同学的学号、姓名、选课数、总成绩
select s.sno,s.sname,count(c.cno),sum(c.score) from student s left join sc c on s.sno=c.sno group by s.sno,s.sname
--or
select s.sno,s.sname,t.cno_count,t.total_score from student s
left join ( select sno, count(cno) cno_count, sum(score) total_score from sc group by sno) t on s.sno=t.sno
--查询姓“刘”的老师的个数;
select count(*) from teacher where tname like '刘%'
--查询没有学全所有课的同学的学号
select t.sno,t.sname from student t,sc s, course c where .sno=s.sno and s.cno=c.cno group by t.sno,t.sname
having count(s.cno)<Select count(Cno) from course
--查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分
select cno,max(score),min(score) from sc group by cno
--查询每门课程被选修的学生数和及格率
select c.cno,count(s.sno), sum(case when score>60 then 1 else 0 end)/count(sno) rate from course c left join sc s on c.cno=s.cno group by cno
--查询两门以上不及格课程的同学的学号及其平均成绩
select c.sno,avg(c.score) from(select s.sno,s.cno,s.score from sc s where s.score<60 group by s.cno) c group by c.sno having count(c.cno)>=2
3.6:嵌套子查询
- 概念:一个查询语句的查询结果作为另一个查询语句的条件,这样的SELECT语句为“子查询”,亦称“嵌套查询”。
SELECT <查询列表> [ INTO <新表名> ]
FROM <基表名|视图名> [ 别名 ] ……
WHERE <列名或列表达式> <比较运算符>
( SELECT <查询列>
FROM <基表名|视图名> [ 别名 ] ……
WHERE <条件表达式>
[ GROUP BY <分组内容>]
[ HAVING <组内条件>] )
[ GROUP BY <分组内容>]
[ HAVING <组内条件>]
[ ORDER BY <排序列名>[ ASC | DESC ] ]
/* 子查询:从emp数据表中查询姓名为WARD的员工的薪水
父查询:找出emp数据表中薪水大于等于WARD的薪水的员工*/
SELECT emp.empno, emp.ename, emp.job, emp.sal
FROM emp
WHERE sal >= (SELECT sal FROM emp WHERE ename='WARD' )
3.7:Union查询
- 概念:将两个或多个查询的结果合并成一个结果返回 。
- 语法:<SELECT语句> UNION [ALL] <SELECT语句>
用UNION合并的结果集应有相同的结构,即列数相同、对应列数据类型兼容。
最后结果的列名取自第一个SELECT语句返回的列名。
默认情况下,最后结果会去掉重复行;但如有ALL选项,则保留重复行。
一般,UNION个数不限,且按从左至右顺序执行。
当用UNION时,各个SELECT语句不能有ORDER BY和COMPUTE子句,而只能在最后一个SELECT语句后带一个ORDER BY和COMPUTE子句,它们是针对最后结果的。不过,各个SELECT语句可用GROUP BY和HAVING子句。
3.8: Select-From-Where 语句的几种写法
- 对T、C、S、SC四个关系,检索学习课程号为C2课程的学生学号与姓名。有四种写法:
--(1)连接查询
SELECT Students.sid, Sname
FROM Students,SC
WHERE Students.sid=SC.sid AND SC.cid='0002'
--2)嵌套查询
SELECT sid, Sname FROM Students
WHERE sid IN(SELECT sid FROM SC WHERE cid='0002')
--3)相关子查询:子查询中查询条件依赖于外层查询中的某个值,所以子查询的处理不止一次,要反复查询,以供外层查询使用
SELECT Students.sid, Sname
FROM Students
WHERE '0002' IN(SELECT cid FROM SC WHERE sid=Students.sid)
4)使用存在量词的嵌套查询
SELECT sid, Sname
FROM Students
WHERE EXISTS(
SELECT *
FROM SC
WHERE SC.sid=Students.sid AND cid='0002')
EXISTS --表示内层查询结果应该为非空。