数据库作业8 SQL练习 ELECT(嵌套查询EXISTS、集合查询、基于派生表的查询)

EXISTS谓词

  • 存在量词

带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”。
若内层查询结果非空,则外层的WHERE子句返回真值 若内层查询结果为空,则外层的WHERE子句返回假值

由EXISTS引出的子查询,其目标列表达式通常都用 * ,因为带EXISTS的子查询只返回真值或假值,给出列名无实际意义。

NOT EXISTS谓词

若内层查询结果非空,则外层的WHERE子句返回假值
若内层查询结果为空,则外层的WHERE子句返回真值

[例 3.60]查询所有选修了1号课程的学生姓名。


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

[例 3.61] 查询没有选修1号课程的学生姓名。

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

[例 3.62] 查询选修了全部课程的学生姓名。

SELECT Sname
FROM Student
WHERE NOT EXISTS
(SELECT *
FROM Course
WHERE NOT EXISTS
(SELECT *
 FROM SC
 WHERE Sno= Student.Sno
  AND Cno= Course.Cno
 )
);
  • 用EXISTS/NOT EXISTS实现逻辑蕴涵

SQL语言中没有蕴涵逻辑运算 可以利用谓词演算将逻辑蕴涵谓词等价转换为:
在这里插入图片描述

[例 3.63]查询至少选修了学生201215122选修的全部课程的学生号码。
用NOT EXISTS谓词表示:

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));

[例 3.64] 查询计算机科学系的学生及年龄不大于19岁的学生。

SELECT *
FROM Student
WHERE Sdept= 'CS'
UNION
SELECT *
FROM Student
WHERE Sage<=19;

UNION:将多个查询结果合并起来时,系统自动去掉重复元组 UNION ALL:将多个查询结果合并起来时,保留重复元组

[例 3.65] 查询选修了课程1或者选修了课程2的学生。

    SELECT Sno
    FROM SC
    WHERE Cno=' 1 '
    UNION
    SELECT Sno
    FROM SC
    WHERE Cno= ' 2 ';

[例 3.66] 实际上就是查询计算机科学系中年龄不大 于19岁的学生。

	    SELECT *
    	FROM Student
    	WHERE Sdept= 'CS' AND  Sage<=19;

[例 3.67]查询既选修了课程1又选修了课程2的学生。

 SELECT Sno
FROM SC
WHERE Cno=' 1 ' 
INTERSECT
SELECT Sno
FROM SC
WHERE Cno='2 ';

[例3.67]也可以表示为嵌套查询:

     SELECT Sno
      FROM    SC
      WHERE Cno=' 1 ' AND Sno IN
      (SELECT Sno
      FROM SC
      WHERE Cno=' 2 ');

[例 3.68] 查询计算机科学系的学生与年龄不大于19岁的学生的差集。

SELECT *
FROM Student
WHERE Sdept='CS'
EXCEPT
SELECT  *
FROM Student
WHERE Sage <=19;

子查询不仅可以出现在WHERE子句中,
还可以出现在FROM子句中,
这时子查询生成的临时派生表成为主查询的查询对象。

[例3.57改]找出每个学生超过他自己选修课程平均成绩的课程号

SELECT Sno, Cno
FROM SC, (SELECT  Sno, Avg(Grade) 
                    FROM   SC 
		           GROUP BY   Sno)
                    AS   Avg_sc(avg_sno,avg_grade)
WHERE SC.Sno = Avg_sc.avg_sno
                    and SC.Grade >=Avg_sc.avg_grade

[例60改]查询所有选修了1号课程的学生姓名,可以用如下查询完成:

SELECT Sname
FROM     Student,  
(SELECT Sno FROM SC WHERE Cno=' 1 ') AS SC1
WHERE  Student.Sno=SC1.Sno;

SELECT子句:
DISTINCT:消除取值重复的行。如果没有指定DISTINCT关键词,则缺省为ALL。
目标列表达式:指定要显示的属性列。查询全部列(
)。可以是算术表达式、字符串常量、函数等。
FROM子句:指定查询对象。
基于派生表的查询AS
WHERE子句:指定查询条件。逻辑运算符AND和 OR连接多个查询条件。比较大小、确定范围 (BETWEEN AND)、确定集合 IN ()、 字符匹配([NOT] LIKE)。
连接查询:WHERE子句中用来连接两个表的条件,格式:[<表名1>.]<列名1> <比较运算符> [<表名2>.]<列名2>。自身连接FROM必须使用“别名”。
GROUP BY子句:对查询结果按指定列的值分组,该属性列值相等的元组为一个组。通常会在每组中作用聚集函数。
HAVING短语:只有满足指定条件的组才予以输出。
聚集函数只能用于SELECT子句和GROUP BY子句中的HAVING子句。如果未对查询结果分组,聚集函数将作用于整个查询结果。对查询结果分组后,聚集函数将分别作用于每个组 。按指定的一列或多列值分组,值相等的为一组。
HAVING短语与WHERE子句的区别:作用对象不同
WHERE子句作用于基表或视图,从中选择满足条件的元组;
HAVING短语作用于组,从中选择满足条件的组。
嵌套查询:将查询块嵌套在WHERE子句或HAVING短语的条件中。(带IN谓词、带比较运算符、带有ANY或ALL谓词的子查询)
*

ORDER BY子句:只对最终查询结果按一个或多个属性列排序。缺省值为升序ASC;降序DESC。

发布了11 篇原创文章 · 获赞 6 · 访问量 2708

猜你喜欢

转载自blog.csdn.net/lrx359641708/article/details/105028115