数据库系统概论(超详解!!!) 第三节 关系数据库标准语言SQL(Ⅳ)

1.集合查询

集合操作的种类

并操作UNION

交操作INTERSECT

差操作EXCEPT

参加集合操作的各查询结果的列数必须相同;对应项的数据类型也必须相同

复制代码
查询计算机科学系的学生及年龄不大于19岁的学生。
        SELECT *
        FROM Student
        WHERE Sdept= 'CS'
        UNION
        SELECT *
        FROM Student
        WHERE Sage<=19;

UNION:将多个查询结果合并起来时,系统自动去掉重复元组

UNION ALL:将多个查询结果合并起来时,保留重复元组

复制代码
查询选修了课程1或者选修了课程2的学生。

        SELECT Sno
        FROM SC
        WHERE Cno=' 1 '
        UNION
        SELECT Sno
        FROM SC
        WHERE Cno= ' 2 ';

查询计算机科学系的学生与年龄不大于19岁的学生的交集。

SELECT *
FROM Student
WHERE Sdept='CS' 
INTERSECT
SELECT *
FROM Student
WHERE Sage<=19 

实际上就是查询计算机科学系中年龄不大于19岁的学生。

		SELECT *
        	FROM Student
        	WHERE Sdept= 'CS' AND  Sage<=19;

查询既选修了课程1又选修了课程2的学生。
    
	 SELECT Sno
    FROM SC
    WHERE Cno=' 1 ' 
    INTERSECT
    SELECT Sno
    FROM SC
    WHERE Cno='2 ';

也可以表示为:
        
	     SELECT Sno
          FROM    SC
          WHERE Cno=' 1 ' AND Sno IN
                                                (SELECT Sno
                                                 FROM SC
                                                 WHERE Cno=' 2 ');

查询计算机科学系的学生与年龄不大于19岁的学生的差集。

    SELECT *
    FROM Student
    WHERE Sdept='CS'
    EXCEPT
    SELECT  *
    FROM Student
    WHERE Sage <=19;


实际上是查询计算机科学系中年龄大于19岁的学生

        SELECT *
        FROM Student
        WHERE Sdept= 'CS' AND  Sage>19;

2.于派生表的查询

子查询不仅可以出现在WHERE子句中,还可以出现在FROM子句中。

这时子查询生成的临时派生表(Derived Table)成为主查询的查询对象

复制代码
找出每个学生超过他自己选修课程平均成绩的课程号
     
    SELECT Sno, Cno
    FROM SC, (SELECTSno, Avg(Grade) 
                        FROM SC
    			  GROUP BY Sno)
                        AS   Avg_sc(avg_sno,avg_grade)
    WHERE SC.Sno = Avg_sc.avg_sno
                   and SC.Grade >=Avg_sc.avg_grade

如果子查询中没有聚集函数,派生表可以不指定属性列,子查询SELECT子句后面的列名为其缺省属性。

复制代码
查询所有选修了1号课程的学生姓名,可以用如下查询完成:
    SELECT Sname
    FROM     Student,  
                   (SELECT Sno FROM SC 
                    WHERE Cno='  1 ') AS SC1
    WHERE  Student.Sno=SC1.Sno;

3.Select语句的一般形式

SELECT [ALL|DISTINCT]

<目标列表达式> [别名] [ ,<目标列表达式> [别名]] ...

FROM <表名或视图名> [别名]

,\<表名或视图名\> \[别名\]\] ... \|(\)\[AS\]\<别名\> \[WHERE \<条件表达式\>

GROUP BY \<列名1\>\[HAVING\<条件表达式\>\]

ORDER BY \<列名2\> \[ASC\|DESC\]\]; ### 1. 目标列表达式的可选格式 目标列表达式格式 (1) \* (2) \<表名\>.\* (3) COUNT(\[DISTINCT\|ALL\]\* ) (4) \[\<表名\>.\]\<属性列名表达式\>\[,\<表名\>.\]\<属性列名表达式\>\]... 其中\<属性列名表达式\>可以是由属性列、作用于属性列 的聚集函数和常量的任意算术运算(+,-,\*,/)组成的 运算公式 ### 2. 聚集函数的一般格式 ![](https://file.jishuzhan.net/article/1776583064202252290/68dbbb0839a217b303fd20c3c44af2d3.webp) ### 3. WHERE子句的条件表达式的可选格式 ![](https://file.jishuzhan.net/article/1776583064202252290/1da009514afadb76467cdc894ff85215.webp) ![](https://file.jishuzhan.net/article/1776583064202252290/ba35892634bf5511a74c9f6a1522fb75.webp) ![](https://file.jishuzhan.net/article/1776583064202252290/1acdee07c5d03e7adba01fcf19741c8e.webp) ## 4.练习 /*(1)查询选修了81003号课程的学生姓名;*/ /*方法1:连接查询*/ select sname from Student,SC where Student.Sno=SC.Sno and SC.Cno='81003'; /*方法2:嵌套in*/ select sname from Student where Sno in (select Sno from SC where Cno='81003'); /*方法3:嵌套exists*/ select sname from Student where exists (select * from SC where Sno=Student.Sno and Cno='81003'); /*(2)查询选修了学分为3的课程的学生学号和姓名;*/ /*方法1:连接查询*/ select Student.Sno ,student.sname from Student,SC,Course where Student.Sno=SC.Sno and SC.Cno=Course.Cno and Ccredit='3'; /*方法2:嵌套in*/ select Sno ,sname from Student where Sno in (select Sno from SC where Cno in (select Cno from Course where Ccredit='3')); /*(3)找出每个超过其所在专业平均年龄的学号,姓名和年龄*/ /*方法1:嵌套相关查询*/ select sno,sname,YEAR(GETDATE())-YEAR(sbirthdate)as'年龄' from Student where YEAR(GETDATE())-YEAR(sbirthdate)> any(select AVG(YEAR(GETDATE())-YEAR(sbirthdate)) from Student group by Smajor); /*方法2:派生表*/ select distinct sno,sname,YEAR(GETDATE())-YEAR(sbirthdate)as'年龄' from Student x,(select AVG(YEAR(GETDATE())-YEAR(sbirthdate)) from Student y group by y.Smajor) as avg_sex(sex) where YEAR(GETDATE())-YEAR(sbirthdate)>avg_sex.sex; /*(4)查询学分大于"操作系统"的所有课程名称;*/ /*方法1:嵌套>*/ select Cname from Course where Ccredit >(select Ccredit from Course where Cname='操作系统'); /*方法2:嵌套exists*/ select Cname from Course x where exists(select * from Course y where x.Ccredit>y.Ccredit and y.Cname='操作系统'); /*(5)查询没有选"数据库"的学生学号;*/ /*方法1:嵌套exists*/ select distinct Sno from SC x where not exists(select * from SC y where y.Sno=x.Sno and exists(select * from Course where Cno=y.Cno and Cname='数据库系统概论') ); /*方法2:集合差*/ select distinct sno from SC except select Sno from Course,SC where Course.Cno=SC.Cno and Cname='数据库系统概论'; /*方法3:not in*/ select distinct Sno from SC where Sno not in (select Sno from SC where Cno in (select Cno from Course where Cname='数据库系统概论') ); /*(6)查询与"数据库"、"数学"学分不同的所有课程名称;*/ /*方法1:not in*/ select Cname from Course where Ccredit not in (select Ccredit from Course where Cname in (select Cname from Course where Cname in('数据库系统概论','离散数学') )); /*方法3:<> all或者any*/ select Cname from Course where Ccredit <> any(select Ccredit from Course where Cname in (select Cname from Course where Cname in('数据库系统概论','离散数学') )); /*(7)查询平均分大于等于80分的所有课程号和课程名称;*/ /*方法1:连接查询*/ select Course.Cno,Cname from Course,SC where Course.Cno=SC.Cno group by Course.Cno,Cname having AVG(Grade)>='80'; /*方法2:派生表*/ select Course.Cno,Cname from Course,(select cno from SC group by Cno having AVG(Grade)>='80')as avg_sc(avg_cno) where Course.Cno=avg_sc.avg_cno group by Course.Cno,Cname /*(8)查询同时选修了'81001'和'81002'号课程的学生学号和姓名;*/ /*方法1:自身连接*/ select student.Sno,Sname from Student ,SC s1,SC s2 where Student.Sno=s1.Sno and s1.Sno=s2.Sno and s1.Cno='81001' and s2.Cno='81002' group by Student.Sno,Sname; /*方法2:嵌套in*/ select Sno,Sname from Student where Sno in (select Sno from SC where Cno = '81001'and Sno in (select Sno from SC where Cno='81002')); /*方法3:集合*/ select student.Sno,Sname from Student ,SC where Student.Sno=sc.Sno and Cno='81001' INTERSECT select student.Sno,Sname from Student ,SC where Student.Sno=SC.Sno and Cno='81002'; /*(9)查询同时选修了'数据库系统概论'和'数据结构'的学生学号和姓名;*/ /*方法1:嵌套in*/ select Sno,Sname from Student where Sno in (select Sno from SC where Cno in (select Cno from Course where Cname = '数据库系统概论') and Sno in (select Sno from SC where Cno in (select Cno from Course where Cname='数据结构'))); /*方法2:集合*/ select Student.Sno,Sname from Student,(select Sno from SC where Cno in (select Cno from Course where Cname = '数据库系统概论'))as x_sc(sno) where Student.Sno=x_sc.sno intersect select Student.Sno,Sname from Student,(select Sno from SC where Cno in (select Cno from Course where Cname='数据结构'))as y_sc(sno) where Student.Sno=y_sc.sno /*(10)查询所有学生都选了的课程号;*/ /*嵌套exists,不存在一个学生没选的课程*/ SELECT Cno FROM Course WHERE NOT EXISTS (SELECT * FROM Student WHERE NOT EXISTS (SELECT * FROM SC WHERE Sno= Student.Sno AND Cno= Course.Cno ) ); /*(11)查询与"数据结构"具有相同先修课的课程号和课程名;*/ /*方法1:自身连接*/ select c1.Cno,c1.Cname from Course c1,Course c2 where c1.Cpno=c2.Cpno and c2.Cname='数据结构' and c1.Cname<>'数据结构'; /*方法2:嵌套in*/ select Cno,Cname from Course where Cname<>'数据结构' and Cpno in (select Cpno from Course where Cname='数据结构'); /*方法3:嵌套exists*/ select Cno,Cname from Course x where Cname<>'数据结构' and exists (select * from Course y where y.Cpno=x.Cpno and Cname='数据结构'); /*方法4:派生表*/ select Cno,Cname from Course,(select Cpno from Course where Cname='数据结构')as xcourse(scpno) where Cname<>'数据结构'and Cpno=xcourse.scpno; /*(12)查询所有具有不及格记录的学生学号和姓名*/ /*方法1:连接查询*/ select Student.Sno,Sname from Student,SC where Student.Sno=SC.Sno group by Student.Sno,Sname,Grade having Grade<'60'; /*方法3:嵌套in*/ select Sno,Sname from Student where Sno in (select Sno from SC where Grade<'60'); /*方法3:嵌套exists*/ select Sno,Sname from Student where exists(select * from SC where sno=Student.Sno and Grade<'60'); /*方法4:派生表*/ select Student.Sno,Sname from Student,(select Sno from SC where Grade<'60')as xsc(sno) where Student.Sno=xsc.sno group by Student.Sno,Sname /*(13)查询计算机科学与技术专业学生选修的所有课程号;*/ /*方法1:连接查询*/ select SC.Cno from Student,SC where Student.Sno=SC.Sno group by SC.Cno,Smajor having Smajor='计算机科学与技术'; /*方法2:嵌套in*/ select distinct Cno from SC where Sno in (select Sno from Student where Smajor='计算机科学与技术'); /*方法3:嵌套exists*/ select distinct Cno from SC where exists(select * from Student where Sno=SC.Sno and Smajor='计算机科学与技术'); /*方法4:派生表*/ select Cno from SC,(select Sno from Student where Smajor='计算机科学与技术')as xstudent(sno) where xstudent.sno=SC.Sno group by Cno; /*(14)查询所有计算机科学与技术专业学生都选的课程号;*/ SELECT Cno FROM Course WHERE NOT EXISTS (SELECT * FROM Student WHERE NOT EXISTS (SELECT * FROM SC WHERE Sno= Student.Sno AND Cno= Course.Cno )and Smajor='计算机科学与技术' ); /*(15)查询选修了81003号课程并且不及格的学生姓名*/ /*方法1:多表连接法*/ select Sname from Student,SC where Student.Sno=SC.Sno group by Student.Sno,Sname,Grade,Cno having Grade<'60'and Cno='81003'; /*方法2:嵌套in*/ select Sname from Student where Sno in (select Sno from SC where Grade<'60'and Cno='81003'); /*方法3:交集*/ select Sname from Student,SC where Student.Sno=SC.Sno group by Student.Sno,Sname,Grade,Cno having Grade<'60' intersect select Sname from Student,SC where Student.Sno=SC.Sno group by Student.Sno,Sname,Grade,Cno having Cno='81003'; /*方法4:派生表*/ select Sname from Student,(select Sno from SC where Grade<'60'and Cno='81003')as xsc(sno) where Student.Sno=xsc.sno group by Sname; /*方法5:嵌套exists*/ select Sname from Student where exists(select * from SC where Sno=Student.Sno and Grade<'60'and Cno='81003'); /*(16)查询选修了"数据库系统概论"并且不及格的学生姓名*/ /*方法1:多表连接法*/ select Sname from Student,SC,Course where Student.Sno=SC.Sno and SC.Cno=Course.Cno group by Student.Sno,Sname,Grade,Cname having Grade<'60'and Cname='数据库系统概论'; /*方法2:嵌套in*/ select Sname from Student where Sno in (select Sno from SC where Grade<'60'and Cno in (select Cno from Course where Cname='数据库系统概论')); /*方法3:交集*/ select Sname from Student,SC where Student.Sno=SC.Sno group by Student.Sno,Sname,Grade having Grade<'60' intersect select Sname from Student,SC,Course where Student.Sno=SC.Sno and SC.Cno=Course.Cno group by Student.Sno,Sname,Cname having Cname='数据库系统概论'; /*方法4:派生表*/ select Sname from Student,(select Sno,Cno from SC where Grade<'60')as xsc(sno,cno),(select Cno from Course where Cname='数据库系统概论')as xcourse(cno) where Student.Sno=xsc.sno and xsc.cno=xcourse.cno group by Sname; /*(17)查询计算机科学与技术专业选修了"数据库系统概论"课且成绩及格的所有学生的学号和姓名;*/ /*方法1:多表连接法*/ select Student.Sno,Sname from Student,SC,Course where Student.Sno=SC.Sno and SC.Cno=Course.Cno group by Student.Sno,Sname,Grade,Cname,Smajor having Grade>'60'and Cname='数据库系统概论'and Smajor='计算机科学与技术'; /*方法2:嵌套in*/ select Sno,Sname from Student where Smajor='计算机科学与技术' and Sno in (select Sno from SC where Grade>'60'and Cno in (select Cno from Course where Cname='数据库系统概论') ); /*方法3:交集*/ select Student.Sno,Sname from Student,SC where Student.Sno=SC.Sno group by Student.Sno,Sname,Grade having Grade>'60' intersect select Student.Sno,Sname from Student,SC,Course where Student.Sno=SC.Sno and SC.Cno=Course.Cno group by Student.Sno,Sname,Grade,Cname,Smajor having Cname='数据库系统概论' intersect select Sno,Sname from Student where Smajor='计算机科学与技术'; /*方法4:派生表*/ select Student.Sno,Sname from Student,(select Sno,Cno from SC where Grade>'60')as xsc(sno,cno),(select Cno from Course where Cname='数据库系统概论')as xcourse(cno) where Student.Sno=xsc.sno and xsc.cno=xcourse.cno and Smajor='计算机科学与技术' group by Student.Sno,Sname; /*(18)查询与"刘晨"同岁且不与"刘晨"在同一个系的学生学号与姓名;*/ /*方法1:嵌套in*/ select Sno,Sname from Student where Sname<>'刘晨' and YEAR(GETDATE())-YEAR(sbirthdate)in (select YEAR(GETDATE())-YEAR(sbirthdate) from Student where Sname='刘晨')and Smajor not in (select Smajor from Student where Sname='刘晨'); /*方法2:嵌套exists*/ select Sno,Sname from Student x where Sname<>'刘晨' and exists(select * from Student y where YEAR(GETDATE())-YEAR(y.sbirthdate)=YEAR(GETDATE())-YEAR(x.sbirthdate)and y.Sname='刘晨') and not exists(select * from Student z where z.Smajor=x.Smajor and z.Sname='刘晨'); /*方法3:派生表*/ select Student.Sno,Sname from Student,(select Sno,YEAR(GETDATE())-YEAR(sbirthdate) from Student where Sname='刘晨')as ystudent(sno,sex),(select Sno,Smajor from Student where Sname='刘晨')as zstudent(sno,smajor) where Sname<>'刘晨'and YEAR(GETDATE())-YEAR(sbirthdate)=ystudent.sex and Student.Smajor<>zstudent.smajor

相关推荐
繢鴻12 分钟前
数据库优化实战分享
数据库
Cachel wood1 小时前
后端开发:计算机网络、数据库常识
android·大数据·数据库·数据仓库·sql·计算机网络·mysql
暗离子跃迁1 小时前
达梦数据库单机部署dmhs同步复制(dm8->kafka)
linux·运维·数据库·分布式·学习·kafka·达梦数据库
LUCIAZZZ1 小时前
项目拓展-Apache对象池,对象池思想结合ThreadLocal复用日志对象
java·jvm·数据库·spring·apache·springboot
水木石画室2 小时前
Druid 连接池详解
数据库·mysql
yzpyzp2 小时前
gradle的 build时kaptDebugKotlin 处理数据库模块
android·数据库
软件2052 小时前
【redis——缓存雪崩(Cache Avalanche)】
数据库·redis·缓存
訾博ZiBo3 小时前
使用 Navicat 成功导入 2.73GB 超大 SQL 文件的实战经验(Win10,64GB内存)
数据库·mysql
小胖同学~3 小时前
SQL 增删改查 —— 笔记篇
服务器·数据库
梦兮林夕3 小时前
Docker + Gin + Gorm Gen:现代 Go Web 开发高效数据库实践
数据库·go·gin