关系代数中的除操作怎么用SQL语句表示?
除运算是什么?(如果已经会了的请直接跳过)
要理解除操作,我们首先要引入“象集”这个概念。
象集
其实象集很简单,就跟我们学过的函数对应关系差不多,只不过函数是“一对一”或者“多对一”,而象集恰好相反,是“一对多”。
引入一个例子看看。假设我们有一张学生选课表SC(sno, cno, grade),其中sno的学生的学号,cno是课程号,grade是分数。这张表记录了学生选修某门课的成绩。
sno | cno | grade |
---|---|---|
2020001 | 001 | 93 |
2020001 | 002 | 95 |
2020001 | 003 | 90 |
2020002 | 001 | 98 |
2020002 | 003 | 87 |
2020003 | 002 | 75 |
(备注:一共只有三门选修课:“001”,“002”,“003”)
我们不给出“象集”的任何定义,先直接求出象集,求完之后,你也就明白了,注意前面说的一对多的关系。
2020001的象集{(001,93),(002,95), (003,90)}
2020002的象集{(001,98),(003,987)}
2020003的象集{(002,75)}
除运算
有了象集的概念后,我们现在来理解“除运算”。假设我们有两个关系R(X,Y)和关系S(Y,Z),那么
R÷S = { tr[X] | tr∈R ∧ ∏Y(S)⊆Yx } 其中Yx为x在R中的象集。
是不是懵逼了?什么鬼东西?
其实啊,这都是纸老虎,没那么难!我们只需要从列(属性)和行(元组)来理解就可以了。
列(属性):R ÷ S得到的新的关系(表),它的列是从R中的列中去掉R和S相交的列。
行(元组):R中每一个x对应的象集应该包含S的投影
这就是“除运算”,这么说可能还是有些抽象,我们继续用上面给出的学生选课例子来研究,为了方便我们暂时先将SC的grade属性去掉,然后我们再加一个课程关系C(cno,cname)
SC:
sno | cno |
---|---|
2020001 | 001 |
2020001 | 002 |
2020001 | 003 |
2020002 | 001 |
2020002 | 003 |
2020003 | 002 |
C:
cno | cname |
---|---|
001 | 操作系统 |
002 | 计算机网络 |
003 | 数据结构 |
我们通过这两个表求SC÷C,我们从列和行两个步骤来进行求解。
第一步(列):SC和C公共的列是cno,所以R÷S必然只剩下R中的sno列,故列先被确定下来了
SC÷C
sno |
---|
2020001 |
2020001 |
2020001 |
2020002 |
2020002 |
2020003 |
第二步(行):
C的投影为(001,002,003),而SC中sno的象集中包含(001,002,003)的只有2020001,故,行也被确定下来了
SC÷C
sno |
---|
2020001 |
聪明的你可能已经发现,SC÷C表示的含义是“查询选修了全部课程的学生”,其实除操作非常适合用于求“至少使用了…的全部”之类的查询
落地到SQL语句的实现
我们刚刚讨论了除操作的关系代数,那么怎么用SQL语句来表示呢?事实上,sql语言并没有定义除操作,甚至连全称量词都没有,但是有存在量词EXISTS 和 NOT EXISTS,所以通常的思路就是将全程量词转变为存在量词来实现除操作。这种也是大多数教材普遍的讲法,但是我们今天不用这种方法,因为那种方法有些绕,使得我们很容易看懂别人写的,但是让自己写却写不出来。所以我们用另一种非常好理解的方式:从除操作的定义出发来解决,不过这要求我们知道什么是右外连接,不用慌,活着就是为了折腾,我都为你准备好了。
外连接 & 右外连接
什么是“外连接”呢?这恐怕得从“连接(严格来讲应该是自然连接)”说起!我们还是使用上面的SC表和C表,注意表的变化!
SC:
sno | cno |
---|---|
2020001 | 001 |
2020001 | 002 |
2020001 | 003 |
C:
cno | cname |
---|---|
001 | 操作系统 |
002 | 计算机网络 |
003 | 数据结构 |
004 | 计算机组成原理 |
当我们对两张表做连接的时候,我们会将SC和C中cno相等的元组拼接起来,于是得到新的关系
SC∞C:
sno | cno | cname |
---|---|---|
2020001 | 001 | 操作系统 |
2020001 | 002 | 计算机网络 |
2020001 | 003 | 数据结构 |
细心的你一定发现了,计算机组成原理这么课因为没人选,所以连接运算时就丢失了,这就是所谓的“悬浮元组”。为了让悬浮元组也出现,于是人们就折腾出了外连接、左外连接、右外连接,我们这里直接说右外连接吧。
当C中的元组的cno与SC中的元组的cno没有对应关系的时候,我们不丢弃这个选组,仍然将其显示出来,用NULL填充没有匹配的字段,也就是下面这样:
SC∝C:
sno | cno | cname |
---|---|---|
2020001 | 001 | 操作系统 |
2020001 | 002 | 计算机网络 |
2020001 | 003 | 数据结构 |
NULL | 004 | 计算机组成原理 |
了解了右外连接后我们就可以利用它这个性质来做除运算了。我们再次使用上面的例子(注意SC和C的变化)
SC:
sno | cno | grade |
---|---|---|
2020001 | 001 | 93 |
2020001 | 002 | 95 |
2020001 | 003 | 90 |
2020002 | 001 | 98 |
2020002 | 003 | 87 |
2020003 | 002 | 75 |
C:
cno | cname |
---|---|
001 | 操作系统 |
002 | 计算机网络 |
003 | 数据结构 |
现在我们求选修了全部课程的学生的学号
我们先写关系代数:
① 全部课程的课程号:∏cno(C)
②除:SC ÷ ∏cno(C)
③投影取学号:∏sno(SC ÷ ∏cno(C))
关系代数很容易写出,但是SQL语句稍微有些复杂,现在我们就用外连接来实现。
SQL语句
SELECT DISTINCT sno
FROM SC a
WHERE NOT EXISTS(SELECT * FROM (SELECT sno, cno FROM SC b WHERE a.sno = b.sno) xRIGHT OUTER JOIN (SELECT cno FROM C) yON x.cno = y.cnoWHERE x.sno IS NULL
);
莫慌,我来解释一下这条SQL语句。拿数据说话,注意我调整了一下
SC:
sno | cno | grade |
---|---|---|
2020002 | 002 | 75 |
2020001 | 001 | 93 |
2020001 | 002 | 95 |
2020001 | 003 | 90 |
C:
cno | cname |
---|---|
001 | 操作系统 |
002 | 计算机网络 |
003 | 数据结构 |
外层循环先取出一条记录 SELECT DISTINCT sno FROM SC a
:(2020002, 002, 75)
我们拿到这个学生的学号2020002,然后找出他选修的所有课程:SELECT sno, cno FROM SC b WHERE a.sno = b.sno
:只有一门课002
然后用002与所有课程做外连接,得到如下的结果:
sno | cno |
---|---|
NULL | 001 |
2020002 | 002 |
NULL | 003 |
显然,有两个sno为空了,所以NOT EXISTS不通过,2020002不是选修了全部课程的学生
以同样的方式对2020001操作得到下面的结果
sno | cno |
---|---|
2020001 | 001 |
2020001 | 002 |
2020001 | 003 |
sno没有NULL,所以2020001是选修了全部课程的学生,将其学号输出。
关系代数中的除操作怎么用SQL语句表示?相关推荐
- 总结一些关于操作数据库是sql语句还是存储过程问题
总结一些关于操作数据库是sql语句还是存储过程问题 程序中,你跟数据的交互,需要向数据库拿数据.更改数据库的数据等,这些操作,本身不是程序完成的,而是程序发命令给数据库去做的,不管是通过sql语句方式 ...
- 在 .NET Core 中如何让 Entity Framework Core 在日志中记录由 LINQ 生成的SQL语句
在开发中,我们想在调试中查看EF Core执行的sql语句,可以使用SQL Studio Manager Tools工具,另一种方式是使用EF Core提供的日志.在ASP.NET Core使用Ent ...
- 云服务器怎么执行sql文件在哪里,总结帝国CMS下在PHP文件中怎么调用数据库类执行SQL语句实例...
总结帝国CMS下在PHP文件中怎么调用数据库类执行SQL语句实例 发布时间:2020-10-19 14:58:08 来源:亿速云 阅读:83 作者:小新 这篇文章将为大家详细讲解有关总结帝国CMS下在 ...
- mysql 导入数据库sql语句_mysql中导入数据与导出数据库sql语句
本文章来详细介绍关于mysql中导入数据与导出数据库sql语句,在mysql中常用的导入与导出数据的命令有source与mysqldump大家可参考. 1.例1:连接到本机上的MYSQL 首先在打开D ...
- MySQL中特别实用的几种SQL语句
MySQL中特别实用的几种SQL语句 文章目录 MySQL中特别实用的几种SQL语句 1. 插入或替换 2. 插入或更新 3. 插入或忽略 4. 指定数据快照或备份 5. 写入查询结果集 6. 强制使 ...
- 删除数据库中所有存储过程和函数的sql语句
-删除数据库中所有存储过程和函数的sql语句 USE [TmpDb] SELECT IDENTITY( INT,1,1 ) flag , [name] NAMES,xtype INT ...
- 实战:从Mysql数据库frm文件中,提取表结构创建SQL语句
需求 在某些特殊的场景下,例如你的mysql数据库无法启动,需要你将表的ibd文件拷贝到另一个数据库中,恢复业务数据库,恢复业务数据的前提,是你需要在另一个数据库中,创建好一模一样的表结构.这时你就需 ...
- mysql查询低效语句_MySQL数据库中查找执行从命慢的SQL语句
MySQL数据库中查找执行从命慢的SQL语句 (2011-09-15 08:21:35) 标签: 杂谈 去历:赛迪网 做者:Alizze 启动Mysql时减参数--log-slow-queries去挤 ...
- mysql创建test_MySQL中,创建数据库test正确的SQL语句是( )
[多选题]PHP中可以实现循环的是(). [填空题]色彩模型是一种抽象的数学模型,即用________来对色彩进行描述的方法. [填空题]人耳可感受声音频率的范围是 HZ . [填空题]PHP中,多行 ...
最新文章
- java图片文件字符串jsp_将图片转成base64字符串并在JSP页面显示的Java代码
- python内置函数源码_python如何查看内置函数源码
- as3.0 比较两个数组
- 出错处理函数abort、exit、atexit、strerror
- python爬取主播信息
- OpenCV中的函数waitKey()函数简介
- win10安装迅雷精简版处理方法---发布者不受信任
- delphi编程来记录QQ的聊天记录
- Intergate flot with Angular js ——Angular 图形报表
- win10环境eclipse安装包双击无反应的解决方案
- 什么是servlet ,servlet的作用
- 基于ThinkPHP5+MySQL的超市进销存管理系统
- MATLAB与高等数学--dsolve命令
- 《通信原理》awgn信道仿真
- salesforce chatter提醒带Mention(即@)
- 当Myeclipse或者Eclipse出现launching client
- 倍福---PLC 字符串类型string操作
- python寻峰算法_python中的快速寻峰与质心
- Elasticsearch搜索引擎一些参数含义和用法
- html中h3字体不加粗取消,css如何取消加粗