SQL 数据查询(3)

本文深入探讨SQL查询中的连接操作,包括等值与非等值查询、自身连接、左/右外连接和多表连接。通过实例解析了如何查询学生选课信息、课程的先修课以及不同类型的连接查询在实际问题中的应用。强调了在外连接中指定连接类型的重要性,并展示了连接查询简化代码的方式。
摘要由CSDN通过智能技术生成

本文中的Student、Course、SC表依次如下:
在这里插入图片描述

连接查询

等值与非等值查询

连接查询WHERE子句中用来连接两个表的条件称为连接条件或连接谓词

[<表名1>.] <列名1> <比较运算符> [<表名2>.] <列名2>

e.g. Student.Sno = SC.Sno
比较运算符主要有= > < >= <= != <>[<表名1>.] <列名1> BETWEEN [<表名2>.] <列名2> AND [<表名3>.] <列名3>

连接条件中的各连接字段类型必须是可比的,但名字不一定要相同

例3.49:查询每个学生及其选修课程的情况

SELECT *
FROM Student,SC
WHERE Student.Sno = SC.Sno;

运行结果如图:
在这里插入图片描述
这里书上明显写的就比较繁琐:

SELECT Student.*,SC.*
FROM Student,SC
WHERE Student.Sno = SC.Sno;

在等值连接中把目标列中重复的属性列去掉则为自然连接

例3.50:对例3.49用自然连接完成

SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
--这里的Sno一定要加Student来修饰,因为他在两个表格中是有重复出现的
--而其他属性都是唯一存在的,所以直接列举出来就好
FROM Student,SC
WHERE Student.Sno = SC.Sno;

在这里插入图片描述

一条SQL语句即可同时完成选择和连接查询

例3.51:查询选修2号课程且成绩在86分以上的所有同学的学号和姓名

这道题要的学号我们暂且使用SC表中的

SELECT SC.Sno,Student.Sname
FROM SC,Student
--FROM操作即为连接操作
WHERE Student.Sno = SC.Sno AND SC.Cno = '2' AND SC.Grade > 86--WHERE AND操作即为选择操作

在这里插入图片描述

自身连接

顾名思义,就是一个表和自己相连

例3.52:查询每一门课的间接选修课(先修课的先修课)

SELECT FIRST.Cno SECOND.Cpno
FROM Course FIRST,Course SECOND
WHERE SECOND.Cno = FIRST.Cpno;

在这里插入图片描述

SELECT FIRST.Cno SECOND.Cpno
FROM Course FIRST,Course SECOND
--WHERE SECOND.Cno = FIRST.Cpno;

这里如果去掉最后一行的修饰条件的话,即是两张表的笛卡尔积
在这里插入图片描述
因为在标准SQL语句中自身连接后不应该出现NULL的组,所以调试一下代码,获得如下的结果

SELECT * --FIRST.Cno,SECOND.Cpno
FROM Course FIRST,Course SECOND
WHERE SECOND.Cno = FIRST.Cpno;

在这里插入图片描述     在这里插入图片描述

比对两组结果的第三行可推测其中的原理:

现象:操作系统(4)的先行课是数据处理(6),然而数据处理(6)是没有先行课的,也就是先行课列属性值为NULL,不符合题目要求

推测:可能在这里NULL也被当成是一种值,SQL没有进行处理优化,可能只是单纯的比较了FIRST.Cpno = Second.Cno,相等的话就直接把Second.Cpno的值打印出来,没有判断Second.Cpno的值是否是NULL

外连接

简而言之就是空余的地方被赋予NULL的一种连接

左外连接:列出左边关系中所有的元组
右外连接:列出右边关系中所有的元组

例3.53

SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM Student LEFT OUTER JOIN SC
ON (Student.Sno = SC.Sno);

在这里插入图片描述
自己又试了一下右外连接,结果右表NULL的地方,左边相对应的元组直接舍弃了,结果如下:

SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM Student RIGHT OUTER JOIN SC
ON (Student.Sno = SC.Sno);

在这里插入图片描述
又试了一下把LEFT去掉,发现报错了,看来外连接的时候必须要指定是左外连接还是右外连接

!!这是错误的代码!!

SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM Student OUTER JOIN SC
ON (Student.Sno = SC.Sno);

在做外连接的时候,SELECT指定要连接的属性,这个是自己根据表格去指定,一般格式应如下:

!!外连接的一般格式!!

SELECT 属性
FROM 第一个表 LEFT/RIGHT OUTER JOIN 第二个表
ON 条件

对于此题,又换了一种写法:

SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM Student,SC
WHERE Student.Sno = SC.Sno;

运行结果是这样的:
在这里插入图片描述
看来如果直接用WHERE来说明条件进行连接,应该是舍弃含有NULL的元组

多表连接

多表连接就是三个及以上的表格进行连接,连接的过程是两两进行连接(1和2连接成12,再与3连接成为123)

例3.54:查询每个学生的学号、姓名、选修的课程名及成绩

SELECT Student.Sno,Student.Sname,Course.Cname,SC.Grade
--这里我个人为了保险起见,是把所有属性的所属表也都说明了出来
--实际情况是,只要是几个表中唯一的属性值就可以不用将其所属的表写出来
FROM Student,Course,SC
WHERE Student.Sno = SC.Sno AND Course.Cno = SC.Cno;
//WHERE进行选择 AND进行连接

在这里插入图片描述

小结:

这两次实验其实上理论课的时候好好听讲,弄清楚各个语句的逻辑含义,做实验的时候其实誊抄上例题后,自己就可以写成代码,总体上还是比较容易的

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值