数据库
首页 > 数据库> > SQL语句中的限定

SQL语句中的限定

作者:互联网

  1. SELECT 语句中的限定
    DISTINCT可以去重
例1 --在表SC中检索男同学选修的课程号
SELECT DISTINCT C#  //DISTINCT 用于去重
FROM SC, S
WHERE S.S# = SC.S# AND SEX = 'M';

例2 --检索每个学生的出生年份
SELECT S#,SNAME, 2022-AGE AS BIRTH_YEAR
FROM S;
  1. 条件表达式中的算术比较操作
    条件表达式中,可以出现算术比较运算符(<,>, >=, <=, =, !=),也可以用 BETWEEN...AND...比较运算符,限定一个值的范围
例1 --检索18~20岁的学生姓名
	方法1. SELECT SNAME
		   FROM S 
	       WHERE AGE >= 18 AND AGE <= 20;
	方法2. 
	       SELECT SNAME
		   FROM S
		   WHERE AGE BETWEEN 18 AND 20;
  1. 列和基本表的改名操作
    我们可以把列和基本表的一些名字用 AS来改成我们喜欢的名字。
例1 --在S表中检索每个学生的姓名与出生年份,输出列名为“STUDENT_NAME”和“BIRTH_YEAR”
SELECT SNAME AS STUDENT_NAME, 2022-AGE AS BIRTH_YEAR
FROM S;
  1. 字符串的匹配操作
类似于一种模糊查找的功能,可以利用该语句在数据库的前端做模糊查找功能。

条件表达式中字符串匹配操作符是LIKE
在表达式中可以使用两个通配符:
百分号(%):与零个或多个字符组成的字符串匹配。
下划线(_):与单个字符匹配。

例1.--检索以字母D打头的学生姓名。
SELECT SNAME
FROM S
WHERE SNAME LIKE 'D%';
--'D%' 就是以D为开头的学生姓名
--'%D%'就是姓名中包含D的学生姓名
--'%D' 就是以D为结尾的学生姓名

例2. --检索以字母T打头,以M结束的三个字母组成的学生姓名
SELECT SNAME 
FROM S
WHERE SNAME LIKE 'T_M';
  1. 集合的交、并、差操作
    当两个子查询的结果的结构完全一致时,可以让这两个子查询执行交、并、差操作。
    交、并、差的运算符为:INTERSECT UNION EXCEPT
//[ALL]未消除重复元组,相反地[DISTINCT]为消除重复元组
(SELECT 查询语句1)
INTERSECT [ALL]
(SELECT 查询语句2)

(SELECT 查询语句1)
UNION [ALL]
(SELECT 查询语句2)

(SELECT 查询语句1)
EXCEPT [ALL]
(SELECT 查询语句2)
  1. 空值的比较操作
    SQL中允许列值为空,空值用保留字NULL表示。
例1--检索年龄为空值的学生姓名。
SELECT SNAME
FROM S
WHERE SNAME IS NULL;

注意这里,不是 SNAME = NULL 而是 SNAME IS NULL

  1. 集合的比较操作
    SQL提供SELECT语句的嵌套子查询机制。子查询是嵌套在另一个查询中的SELECT语句。

    • 集合成员资格的比较 元组 [NOT] IN (集合)
    • 集合成员的算术比较 元组 θ SOME[ALL] (集合),其中θ指(<,>, >=, <=, =, !=)等算术比较运算符。
    • 空关系的测试 [NOT] EXISTS (集合),EXISTS这个语句,个人理解就是判断后面的东西是不是一个空集合,如果是空集合那EXISTS返回的值就是,否则就为
    • 重复元组的测试 [NOT] UNIQUE (集合)
例1--检索至少不学C2和C4两门课程的学生学号。
--换句话说,找出的同学必须不学C2和C4,其他课可以学也可以不学,但绝不能学C2或C4。
SELECT S#
FROM S
WHERE S# NOT IN (SELECT S# 
				 FROM SC
				 WHERE C# IN ('C2', 'C4'));
解析:先找出选了C2或C4或者两门课都选的同学的学号,构成集合A。再从学生列表中遍历学号,找出不在集合A中的学号。
例2--检索学习C2课程的学号与姓名
1.朴素写法
	SELECT SC.S#, SNAME
	FROM SC, S
	WHERE S.S# = SC.S# AND SC.C# = 'C2'
解析:接做自然连接,然后选择即可。

2.IN写法
SELECT S#, SNAME
FROM S
WHERE S# IN (SELECT S# 
			 FROM SC 
			 WHERE SC.C# = 'C2');
解析:找出学习'C2'课程同学的学号作为集合A,再从S表中,一次便利学号,若该学号在集合A中,选择该行的S#, SNAME。

3. 元组 θ SOME[ALL] (集合) 写法
SELECT S#, SNAME
FROM S
WHERE S# =SOME (SELECT S#
				FROM SC
				WHERE SC.C# = 'C2');
其中,=SOME,就是看 S#是不是等于后面集合中的某个元素,如果有相等的元素,便符合条件。
所以,我们可以看出 =SOME 等价于 IN
例3--检索至少有一门成绩超过学生S4一门成绩的学生学号
SELECT DISTINCT S#
FROM SC
WHERE SC.SCORE >SOME(SELECT SCORE
					FROM SC
					WHERE SC.S# = 'S4')
解析:先找出's4'同学的所有成绩放入集合A,然后最外层遍历所有同学每个课程的成绩,只要存在成绩大于A中的任何一个值,即可将其选出。
也就是有些田忌赛马的意思,可以是语文成绩大于's4'同学的英语成绩。
其实,大于某个集合的一个数,那么就等价于 大于该集合的最小值。
例4--检索不学习C2课程的学生姓名和年龄
1.NOT IN 写法
SELECT SNAME, AGE
FROM S
WHERE S.S# NOT IN (SELECT S#
			       FROM SC
				   WHERE SC.C# = 'C2')
解析:先从SC表中找出所有学习'C2'课程同学的学号,放入集合A中。从S表中遍历所有同学的学号,如果该学号不属于集合A,那么将其选出,否则忽略不计。
				   
2.<>ALL 写法
--检索不学习C2课程的学生姓名和年龄
SELECT SNAME, AGE
FROM S
WHERE S.S# <> ALL (SELECT S#
			       FROM SC
				   WHERE SC.C# = 'C2')
解析:先从SC表中找出所有学习'C2'课程同学的学号,放入集合A中。从S表中遍历所有同学的学号,如果该学号和集合A中的所有学号都不相等,那么将其选出,否则忽略不计。
由此可以看出,NOT IN 等价于 <> ALL
例5--检索平均成绩最高的学生学号
SELECT S#
FROM SC
GROUP BY S#
	HAVING AVG(SC.SCORE) >=ALL (SELECT AVG(SCORE)
								FROM SC
								GROUP BY S#)
解析:子查询中,先按学号分组,查出所有同学的平均成绩,将平均成绩放入集合A中。然后在外层查询依次枚举每个同学的平均成绩,如果该同学的平均成绩>=集合A内的所有成绩,即为平均成绩最高。
小tips:聚合函数不能进行复合运算。
例6--检索学习课程号为C2的学生学号和姓名
SELECT S#, SNAME
FROM S
WHERE EXISTS(SELECT *
			 FROM SC
			 WHERE SC.C# = 'C2' AND S.S# = SC.S#);
  1. 导出表的使用
    SQL允许在FROM子句中使用子查询。如果在FROM子句中使用了子查询,那么要给子查询的结果起个表名和相应的列名。
例1--检索平均成绩超过60分的学生学号和平均成绩
SELECT S#, AVG(SC.SCORE) AS AVGSOCRE
FROM SC
GROUP BY S#
	HAVING AVG(SC.SCORE) > 60;

导出表形式:(应该不常考吧,我猜)
SELECT S#, AVG_SCORE
FROM (SELECT S#, AVG(SCORE)
	  FROM SC
	  GROUP BY S#
	  HAVING AVG(SCORE) > 60) AS RESULT(S#, AVG_SCORE)

标签:语句,SNAME,限定,--,SQL,SC,C2,WHERE,SELECT
来源: https://blog.csdn.net/weixin_63670962/article/details/123571618