数据库Exists关键字举例

一.问题描述:

查询所有未选择03号课程的学生的姓名 规定使用存在量词

student表:

grade表:

二.思路:

既然是存在量词那么也就是Exists和Not Exists两个存在两次来做判断条件。 那么就可以想:

1.选出所有学生然后除去那些选了03号课程的同学

2.直接选出那些没有选择03号课程的同学

三.开始写Sql:

1.尝试

首先按照第一种思路就是先连接student和grade(或者不连接)然后除掉grade中有03课程记录的学生,那么我们会写出以下Sql:

SELECT DISTINCT sname from Student,Grade WHERE NOT exists(
  SELECT * FROM Grade WHERE cno='03'
);
或者
SELECT DISTINCT sname from Student WHERE NOT exists(
  SELECT * FROM Grade WHERE cno='03'
);

执行以后我们发现我们得到的结果是空

接下来我们看看student表中到底有多少人: 执行以下语句:

SELECT DISTINCT sno,sname FROM Student GROUP BY sno;

这里我们发现这条语句根本没有进行筛选,这是因为Exists不知道使用什么条件去筛选数据,前面是一个结果集后面为另一个结果集数据库不清楚按照哪个字段来判断前面的某条记录是否存在与后面的集合中。

2.修正错误:

这里在两个表之间显然只有sno字段是相关的,所以在最后添加判断条件:

Grade.sno=Student.sno
也就是
SELECT DISTINCT sname from Student WHERE NOT exists(
  SELECT * FROM Grade,Student WHERE cno='03' AND Grade.sno=Student.sno
);

此时出现了10条记录经过比对发现是正确的。

3.接下来用sql语句验证结论:

SELECT DISTINCT sno,sname FROM Student GROUP BY sno;
SELECT sno FROM Grade WHERE cno='03';

第一条语句就是找到student表中的所有人,第二条语句就是看看哪些人选择了03号课程,结果如下。

发现结论正确,但是这两个语句貌似可以拼接成一条新的sql来完成这道题:

SELECT DISTINCT sname
FROM Student  where sno NOT IN (
  SELECT sno FROM Grade WHERE cno='03'
);

结果同上。

4.反向思维:

既然not Exists是可以的那么是不是可以把那条语句修改成exists语句然后把where里面的条件再非一下,执行以下语句:

SELECT sname FROM Student WHERE  exists(
    SELECT DISTINCT Student.sno FROM Grade WHERE Grade.sno=Student.sno
    AND cno!='03'
);

但是结论是只有七条数据,显然差距比较大。 也就是子查询是有问题的,查表以后发现在student表中是有十二个同学,但是grade表中选课的同学总数并不是十二个,也就是说有很多人根本没有选课。并且另外一个问题就是有的人选了不止一门课可能某个同学既选了03又选了别的课程,而在使用exits判断的时候只要有满足条件的就返回,自然是没等判断到选了03就能返回真。所以这个方法行不通。

5.修改:

上面出现问题,说明使用exists思路没问题只是子查询错误,试试运用course表看能不能写出其他语句:

SELECT sname FROM Student WHERE  exists(
  SELECT cno FROM Course WHERE sno NOT IN (
    SELECT sno FROM Grade WHERE cno='03'
  )
);

把exits换成IN

SELECT DISTINCT sno
FROM Student  where sno  IN (
  SELECT sno FROM Course WHERE sno NOT IN (
    SELECT sno FROM Grade WHERE cno='03'
  )
);

看以下的句子:

SELECT sname FROM Student WHERE  exists(
  SELECT dno FROM Department WHERE sno NOT IN (
    SELECT sno FROM Grade WHERE cno='03'
  )
);

仔细看就会发现其实上面的句子其实就是:

SELECT DISTINCT sname
FROM Student  where sno NOT IN (
  SELECT sno FROM Grade WHERE cno='03'
);

只是中间添加了一些毫无逻辑的语句,但是对结果没有任何影响。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏码农分享

数据库批量删除

24230
来自专栏面朝大海春暖花开

mybatis递归,一对多代码示例

由于只有这么两级,可以不用使用递归,直接查询父集,之后foreach查询子集放入对应的list集合。

19910
来自专栏IT开发技术与工作效率

MySQL 循环查询树 函数

23850
来自专栏C# 编程

1 - SQL Server 2008 之 使用SQL语句创建具有约束条件的表

约束条件分为以下几种: 1)非空约束,使用NOT NULL关键字; 2)默认值约束,使用DEFAULT关键字; 3)检查约束,使用CHECK关键字; 4)唯一约...

21000
来自专栏性能与架构

mysql 索引无效的情况

下面几种情况下,索引是不会被使用的 (1)组合索引,查询时的条件列不是组合索引中的第一个列 例如 组合索引 (a,b),查询中使用了b作为查询条件,这时是不会用...

44770
来自专栏机器学习算法与Python学习

SQL Server 学习笔记

之前学过一点数据库但由于一直没有使用忘得差不多了,最近重新复习一下相关的知识,把基本的语法YOU又看了一遍,为了强化记忆在写一遍~~~~~~ ? 基本的 se...

383150
来自专栏C# 编程

2 - SQL Server 2008 之 使用SQL语句为现有表添加约束条件

上一节讲的是直接在创建表的时候添加条件约束,但是有时候是在表格创建完毕之后,再添加条件约束的,那么这个又该如何实现? 其实,跟上一节所写的SQL代码,很多是相同...

22700
来自专栏LanceToBigData

MySQL(九)之数据表的查询详解(SELECT语法)一

这一篇是MySQL中的重点也是相对于MySQL中比较难得地方,个人觉得要好好的去归类,并多去练一下题目。MySQL的查询也是在笔试中必有的题目。希望我的这篇博客...

315100
来自专栏跟着阿笨一起玩NET

sql 在not in 子查询有null值情况下经常出现的陷阱

如果下:Table_A表和Table_B表,要求查询出在Table_A表中不在Table_B表中的记录。

26910
来自专栏性能与架构

Mysql group by实现方式(一) - 索引扫描

由于GROUP BY实际上也同样须要进行排序操作,而且与ORDER BY相比,GROUP BY主要只是多了排序之后的分组操作。所以,在GROUP BY的实现过程...

32150

扫码关注云+社区

领取腾讯云代金券