不熟悉SQL查询语句?看这篇就够了!

2022-03-30 12:19:14 浏览数 (1)

一、前言

这学期在上《数据库原理及其应用》这门课,我觉得非常有趣!感觉才学了几节课就已经对数据库有了更深的理解,包括数据库的关系代数语言SQL语言关系数据库的设计等等,这使我马上写了个教务管理系统练练手,并且特意研究设计了多个关系表及其之间的联系,然后建表,创建视图。对于这个项目我之后应该会另发文章介绍,目前写的第一版是用SSM框架 jsp,之后会使用vue框架 springboot改成前后端分离版。

咳咳,偏离主题了!今天我来给大家分享一些我在做SQL查询实验时,大脑不经意间总结出的一些小套路!

众所周知,想实现对一个或多个数据表信息的查询需求,可以用多种的SQL语句形式实现。但是我发现有一种套路是接近万能的!如果你还不熟悉SQL的查询语句,那不妨继续看下去叭!

话不多说,上干货!

二、套路

  1. 观察题目需求, 找到最后要求我们展示的所有属性, 并先写下
代码语言:javascript复制
select attr1, attr2 ... 

2. 看这些属性分别来自于哪些表, 然后把所有涉及到的表名称写到from 后面(下面假设涉及多表)

代码语言:javascript复制
select attr1, attr2 .... from table1, table2 ...

3. 然后再毫不犹豫地在where后面加上各个表的外键属性相等的条件(原理之后介绍)

代码语言:javascript复制
select attr1, attr2.... from table1, table2... where table1.Tno = table2.Tno (and ....)

4. 这时候, 如果题目是简单查询, 那你只用再and上一个或几个条件就好了

代码语言:javascript复制
select attr1, attr2.... from table1, table2... where table1.Tno = table2.Tno (and ....) 
and table1.Tno = val (and ...)

但是有时候题目往往不会很简单, 可能会涉及到嵌套子查询, 那我们就要搬出我们万能的existsnot exists了, 众所周知, 所有谓词的条件都能用这两个来代替。

但是exists和not exists里的子查询,也会是完整的select语句,只是属性不用罗列,写上select * 罢了,但是如果子查询涉及到多个表,那还是只用重复以上的步骤,where上多表之间外键相等的条件,然后再根据题目补充条件就好了。

代码语言:javascript复制
select attr1, attr2.... from table1, table2... where table1.Tno = table2.Tno (and ....) 
and table1.Tno = val (and ...) and exists(
  select * from table3, table4 ... where table3.Tno = table4.Tno (and ...)
)

到这里是不是看上去感觉有点道理,但是没有很深刻的理解呢?不要着急,下面会上例题!

首先解释一下这个套路的合理性,select罗列所有要展示的属性这是必然的,不用多说,而where上外键相等的条件,可能你们在做题时,会不假思索地写上,但是没总结过这是绝对要写的。

因为如果不where上多表之间的外键相等关系,查出来的数据只是多表的笛卡尔积,但是两个关系表在1对1和1对多的关系中(多对多会创建中间表,而每个表和中间表之间也是1对多的关系),一个关系表的元组,肯定是靠它的外键,在另一个关系表中找到和自己有关联的元组信息,而其他没关联的应被舍去。所以外键相等的条件是必然的。

下面上例题

三、实战

样例的表信息:

1.Wangyb_Courses

2.Wangyb_Reports

3.Wangyb_Students

4.Wangyb_Teachers

1.简单查询

(1)查询学号S52的学生的姓名和选修的课程名称及成绩。

1. 首先按照最后要展示的属性,写出

代码语言:javascript复制
Select wyb_Sname, wyb_Cname, wyb_Score

2. 发现涉及到三个表,则接上

代码语言:javascript复制
From Wangyb_Students S, Wangyb_Courses C, Wangyb_Reports R

3. 因为涉及多表,话不多说,接上外键属性相等的条件

代码语言:javascript复制
Where S.wyb_Sno = R.wyb_Sno and C.wyb_Cno = R.wyb_Cno

4. 再接上题目剩下的一个条件

代码语言:javascript复制
And S.wyb_Sno = ‘S52’

这种题就这样被解决了。至于复杂的题目,其实也只是在第3步的基础上and上一个exists或者not exists,在括号中select * from table1, table2,再where上多表的外键相等的条件,再根据题目and上补充的条件即可。

2.复杂查询

(1)查询没有学生选的课程的编号和名称。

1. 首先按照最后要展示的属性,写出

代码语言:javascript复制
Select wyb_Cno, wyb_Cname 

2. 发现只涉及一个表

From Wangyb_Courses

3. 因为题目的需求的不能直接补充and上一个简单条件出来,所以要涉及exists或者not exists

代码语言:javascript复制
Where not exists(
      * 3.1 因为要找出没有学生选的课涉及Wangyb_Students, Wangyb_Reports两个表,那么也一样,外键相等,
      Select * from Wangyb_Students S, Wangyb_Reports R where S.wyb_Sno = R.wyb_Sno 
      * 3.2 再and上补充条件
      and R.wyb_Cno = wyb_Cno
)

最后,完整的语句就是

代码语言:javascript复制
Select wyb_Cno, wyb_Cname from Wangyb_Courses where not exists(
   Select * from Wangyb_Students S, Wangyb_Reports R where S.wyb_Sno = R.wyb_Sno and R.wyb_Cno = wyb_Cno
)

(2)查询所有选了“数据库原理及其应用”课程的学生编号和姓名。

1. 首先按照最后要展示的属性,写出

代码语言:javascript复制
Select wyb_Sno, wyb_Sname 

2. 发现只涉及一个表

代码语言:javascript复制
from Wangyb_Students S 

3. 因为题目的需求的不能直接补充and上一个简单条件出来,所以要涉及exists或者not exists

代码语言:javascript复制
where exists(
   * 3.1 因为要找出没有学生选的课涉及Wangyb_Courses, Wangyb_Reports两个表,那么也一样,外键相等,
   Select * from Wangyb_Reports R, Wangyb_Courses C where R.wyb_Cno = C.wyb_Cno 
   * 3.2 再and上补充条件
   and C.wyb_Cname = '数据库原理及其应用' and S.wyb_Sno = R.wyb_Sno
) 

(3)查询选修了所有课程的学生姓名。(多级嵌套)

这道题在SQL查询中会比较特殊,因为SQL没有直接的语法支持全部,所有等全称量词的查询,所以只能转换思路,查询"没有一个课程这个学生没选的学生姓名", 这里会比较难以理解,一定要先把这个转换搞懂!

1. 首先按照最后要展示的属性,写出

代码语言:javascript复制
Select wyb_Sname 

2. 发现只涉及一个表

代码语言:javascript复制
from Wangyb_Students S 

3. 因为题目的需求的不能直接补充and上一个简单条件出来,所以要涉及exists或者not exists

代码语言:javascript复制
where  not exists(
   select * from Wangyb_Courses C
   * 3.1 据题意,还得where一层not exists
   where not exists(
   * 3.2 这里只涉及单表,
   Select * from Wangyb_Reports R where
   * 3.3 再and上补充条件
   S.wyb_Sno = R.wyb_Sno and C.Cno = R.wyb_Cno
   )
) 

四、总结

怎么样!看完后是不是感觉再拿到SQL查询题时,就知道从哪里对它下毒手了呢?虽然这个套路好用,但也要建立在对多个关系数据表的查询稍微熟练的前提之上,就比如在查询时会涉及嵌套子查询,而嵌套子查询分为相关子查询不相关子查询,而相关子查询就会要在where后面根据题目要求and上父查询涉及到的Father_table和子查询涉及到的Child_table之间的属性关系

0 人点赞