数据库--[复习]---带有EXISTS谓词的子查询---查询语句中含有‘至少’条件的查询

前言

EXISTS代表存在量词∃,带有EEISTS谓词的子查询不反悔任何数据,只产生逻辑真值“true”或逻辑假值“false”。
由EXISTS引出的子查询,其目标列表达式通常都用*,因为EXISTS的子查询只返回真值假值,给出列名无实际意义。

使用到的表/数据

用到的表:

  • 学生表
  • 课程表
  • 学生选课表

学生表:Student(Sno,Sname,Sex,Sage,Sdept)

学号Sno姓名Sname性别Sex年龄Sage所在系Sdept
201215121李勇20CS
201215122刘晨20CS
201215123王敏18MA
201215125张立19IS

课程表:Course(Cno,Cname,Cpno,Ccredit)

课程号Cno课程名Cname先行课Cpno学分Ccredir
1数据库54
2数学3
3信息系统14
4操作系统63
5数据结构74
6数据处理2
7PASCAL语言54

学生选课表:SC(Sno,Cno,Garde)

学号Sno课程号Cno成绩Grade
201215121192
201215121285
201215121388
201215122290
201215122380

建立表的SQL语句

/*建立一个学生表Student*/
CREATE TABLE Student
(Sno CHAR(9) PRIMARY KEY,
 Sname CHAR(20) UNIQUE,
 Ssex char(2),
 Sage SMALLINT,
 Sdept CHAR(20)
 );
/*建立一个课程表 Course*/
 CREATE TABLE Course
 (Cno CHAR(4) PRIMARY KEY,
  Cname CHAR(40) NOT NULL,
	Cpno CHAR(4),
	Ccredit SMALLINT
	);
	
/*建立学生选课表SC*/
	CREATE TABLE SC
	(Sno CHAR(9),
	 Cno char(4),
	 Grade SMALLINT,
	 PRIMARY KEY(Sno,Cno),
	 FOREIGN key(Sno) REFERENCES Student(Sno),
	 FOREIGN key(Cno) REFERENCES Course(Cno)
	 );

插入数据:

/*插入语句*/
INSERT INTO student VALUES('201215121','李勇','男',20,'CS');
INSERT INTO student VALUES('201215122','刘晨','女',19,'CS');
INSERT INTO student VALUES('201215125','张立','男',19,'IS');
INSERT INTO student VALUES('201215123','王敏','女',18,'MA');


INSERT INTO course VALUES('1','数据库','5',4);
INSERT INTO course VALUES('2','数学',' ',2);
INSERT INTO course VALUES('3','信息系统','1',4);
INSERT INTO course VALUES('4','操作系统','6',3);
INSERT INTO course VALUES('5','数据结构','7',4);
INSERT INTO course VALUES('6','数据处理','',2);
INSERT INTO course VALUES('7','PASCAL语言','6',4);
INSERT INTO course VALUES('8','DB_Design','1',3);
INSERT INTO course VALUES('9','DB_DataDesign','8',4);

INSERT INTO sc VALUES('201215121','1',92);
INSERT INTO sc VALUES('201215121','2',85);
INSERT INTO sc VALUES('201215121','3',88);
INSERT INTO sc VALUES('201215122','2',90);
INSERT INTO sc VALUES('201215122','3',80);

例题1

问题:查询所有选修了1号课程的学生姓名。

此查询涉及的表Student和SC表。可以在Student中依次选取每个元组数据的Sno值,用此值去检查SC表。若SC中存在这样的元组,其Sno值等于此Srudent.Sno值并且Cno=1,则取此Student.Sname送入结果表。
对应逻辑的SQL语句:

SELECT Sname
FROM Student
WHERE EXISTS(
SELECT *
FROM SC
WHERE Sno=Student.Sno AND Cno='1'
);

使用EXISTS后,若内层查询结果非空,则外层的WHERE子句返回真值,否则返回假值

运行结果:

在这里插入图片描述
学生选课表表我们可以看到,选修1号课程的只有李勇一个人。所以输出结果是正确的。

例题2

问题:查询至少选修了学生201215122选修的全部课程的学生号码。

问题分析:
要求查出至少选修了学生201215122的全部课程的学生,学生201215122选修的课程包括(2数学、3信息系统),换层意思理解就是,要找出的学生是只要201215122选修的课程他都选了。

本查询可以用逻辑蕴含来表达:查询学号为X的学生,对所有的课程y,只要201215122学生选修了课程y,则x也选修y。
用p表示:“学生201215122选修了课程y”
用q表示:“学生x选修了课程y”

最终可以理解为:不存在这样的y(课程),学生201215122选修了y,而学生x没有选修

SQL语句逻辑:

此SQL语句分三层来理解
第一层,选取学生选课表中的一条数据来,判断这一条数据符不符合条件。
第二层,筛选出201215122学生在学生选课表中的数据。
第三层,判断第一层选出的数据的学生选修的课程,是否包含第二层筛选出来的数据中的课程号。

我们通过图文来理解以下:

在这里插入图片描述
ok,对应的SQL语句为。

SELECT DISTINCT Sno
FROM SC SCX
WHERE NOT EXISTS(
SELECT *
FROM SC SCY
WHERE SCY.Sno='201215122' AND NOT EXISTS(
SELECT *
FROM SC SCZ
WHERE SCZ.Sno = SCX.Sno AND
SCZ.Cno = SCY.Cno));

运行截图:
在这里插入图片描述

END!

  • 12
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gussu-毛虫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值