数据库系统概论(超详解!!!) 第三节 关系数据库标准语言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 <表名或视图名> [别名]

[ ,<表名或视图名> [别名]] ...

|(<SELECT语句>)[AS]<别名>

[WHERE <条件表达式>]

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

[ORDER BY <列名2> [ASC|DESC]];

1. 目标列表达式的可选格式

目标列表达式格式

(1) *

(2) <表名>.*

(3) COUNT([DISTINCT|ALL]* )

(4) [<表名>.]<属性列名表达式>[,<表名>.]<属性列名表达式>]...

其中<属性列名表达式>可以是由属性列、作用于属性列 的聚集函数和常量的任意算术运算(+,-,*,/)组成的 运算公式

2. 聚集函数的一般格式

3. WHERE子句的条件表达式的可选格式

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
相关推荐
hefaxiang20 分钟前
【MYSQL】mysql约束---自增长约束(auto_increment)
数据库·mysql
琴智冰20 分钟前
SpringBoot
java·数据库·spring boot
AAEllisonPang29 分钟前
Oracle 时间计算
数据库·oracle
m0_7164990629 分钟前
达梦8-数据守护集群主备故障实验和脑裂处理
数据库
小登ai学习1 小时前
简单认识 redis -3 -其他命令
数据库·redis·缓存
m0_687399841 小时前
QT combox 前缀匹配
开发语言·数据库·qt
计算机学姐1 小时前
基于微信小程序的调查问卷管理系统
java·vue.js·spring boot·mysql·微信小程序·小程序·mybatis
vvvae12349 小时前
分布式数据库
数据库
雪域迷影10 小时前
PostgreSQL Docker Error – 5432: 地址已被占用
数据库·docker·postgresql
bug菌¹10 小时前
滚雪球学Oracle[4.2讲]:PL/SQL基础语法
数据库·oracle