摘要:在上一个章节数据库管理系统——SQL(概述与数据定义)-CSDN博客中,我们学习了SQL的概述与数据定义,本篇博客将继续讲述SQL的数据查询语句
目录
一、数据查询
查询语法:
SELECT [ALL|DISTINCT ] <目标列表达式> [别名] [,<目标列表达式> [别名] ] …
FROM <表名或视图名> [别名] [,<表名或视图名> [别名] ] ] … | (<SELECT语句>) [ AS ] <别名>
[WHERE <条件表达式> ]
[GROUP BY <列名1> [ HAVING <条件表达式> ] ]
[ORDER BY <列名2> [ ASC|DESC]]
LIMIT <行数1>[ OFFSET <行数2>];
其中:
SELECT语句:指定显示的属性列
FROM子句:指定查询对象(范围)(基本表或视图)
WHERE子句:指定查询条件
GROUP BY子句:结果按照<列名1>的值进行分组,该属性列值相等的元组为一个组,通常在每组中作用聚集函数。
HAVING短语:只有满足指定条件的组才予以输出
ORDER BY子句:对查询结果表按<列名1>的值的升序或降序排序
LIMIT子句:限制SELECT语句查询结果的数量为<行数1>行,OFFSET <行数2>,表示在计算<行数1>行前忽略<行数2>行
在关系数据库的数据查询中可分为单表查询、连接查询、嵌套查询和集合查询,下面将依次讲解
1.1单表查询
顾名思义,单表查询的范围只涉及一个表
例1:查询所有学生的学号与姓名
语法:SELECT Sno,Sname
FROM Student;
例2:查询全体学生的所有信息。
语法:SELECT *
FROM Student;
例3:查询去重后的专业
语法:SELECT DISTINCT Smajor
FROM SC;
使用WHERE查询满足条件的元组
例1:查询主修计算机科学与技术专业全体学生的姓名
语法:SELECT Sname
FROM Student
WHERE Smajor=‘计算机科学与技术’;
例2:查询所有2000年后(包括2000年)出生的学生姓名及其性别
语法:SELECT Sname, Ssex
FROM Student
WHERE extract(year from Sbirthdate)>=2000;
/*函数extract(year from Sbirthdate)从出生日期中抽取出年份*/
例3:查询成绩在60到80之间的学生的姓名和出生日期
语法:SELECT Sname, Sbirthdate
FROM Student
WHERE Grade BETWEEN 60 AND 80;
例4:查询既不是计算机科学与技术专业也不是信息安全专业学生的姓名和性别
语法:SELECT Sname,Ssex
FROM Student
WHERE Smajor NOT IN ( '计算机科学与技术','信息安全' );
使用LIKE进行字符串近似匹配
语法: [NOT] LIKE ‘<匹配串>’ [ESCAPE ‘ <换码字符>’]
<匹配串>:一个完整的字符串或含有通配符%和 _
其中:
% (百分号)表示:任意长度(长度可以为0)的字符串
_ (下横线) 表示:任意单个字符
例1:查询所有姓刘学生的信息:
语法:SELECT *
FROM Student
WHERE Sname LIKE '刘%';
例2:查询名字是两个字,并且以‘航’字结尾的学生信息
语法:SELECT *
FROM Student
WHERE Sname LIKE '_ _航';
例3:查询以“DB_”开头,且倒数第三个字符为 i的课程的详细情况。
语法:SELECT *
FROM Course
WHERE Cname LIKE 'DB\_%i__' ESCAPE '\';
/*ESCAPE '\' 表示将'\'设置为转义字符,\之后的通配符都将视为普通字符*/
涉及空值的查询
例1:查询缺少成绩的学生的学号和相应的课程号
语法:SELECT Sno,Cno
FROM SC
WHERE Grade IS NULL;
多重条件查询AND/OR
例:查询主修计算机科学与技术专业或信息安全专业的学生的姓名和性别
语法:SELECT Sname,Ssex
FROM Student
WHERE Smajor='计算机科学与技术' OR Smajor='信息安全';
使用ORDER BY进行升序(ASC)降序(DESC)显示结果
例:查询选修了81003号课程的学生的学号及其成绩,查询结果按分数的降序排列
语法:SELECT Sno,Grade
FROM SC
WHERE Cno='81003’
ORDER BY Grade DESC;
聚集函数
例1:查询学生总人数
语法:SELECT COUNT(*)
FROM Student;
例2:查询选修了课程的学生人数
语法:SELECT COUNT(DISTINCT Sno)
FROM SC;
例3:计算选修81001号课程的学生平均成绩
语法:SELECT AVG(Grade)
FROM SC
WHERE Cno= ‘ 81001 ';
使用GROUP BY进行分组查询
按指定的一列或多列值分组,值相等的为一组
例1:求各个课程号对应的选修课程的人数
语法:SELECT Cno,COUNT(Sno)
FROM SC
GROUP BY Cno;
例2:查询2024年第2学期选修了10门以上课程的学生学号
语法:SELECT Sno
FROM SC
WHERE Semester='20242' /*先求出2024年第2学期选课的所有学生*/
GROUP BY Sno /*用GROUP BY子句按Sno进行分组*/
HAVING COUNT(*) >10; /* 用聚集函数COUNT对每一组计数 */
//HAVING 用于过滤这些分组的结果。和 WHERE 不同,HAVING 是针对分组后的数据进行过滤,而 WHERE 是针对分组之前的原始数据进行过滤。
例3:查询平均成绩大于等于90分的学生学号和平均成绩
语法:SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno
HAVING AVG(Grade)>=90;
使用LIMIT语句限制查询返回的结果数量
语法:LIMIT <行数1> [ OFFSET <行数2>];
例1:查询选修了数据库系统概论课程的成绩排名前10名的学生学号
语法:SELECT Sno
FROM SC,Course
WHERE Course.Cname='数据库系统概论’
AND SC.Cno=Course.Cno
ORDER BY GRADE DESC
LIMIT 10; /*取前10行数据为查询结果*/
例2:查询平均成绩排名在3-5名的学生学号和平均成绩
语法:SELECT Sno
FROM SC
GROUP BY Sno
ORDER BY AVG(Grade) DESC
LIMIT 5 OFFSET 2; /*取5行数据,忽略前2行,之后为查询结果数据*/
1.2连接查询
连接查询:同时涉及两个以上的表的查询
连接条件或连接谓词:用来连接两个表的条件
一般格式:
[<表名1>.]<列名1> <比较运算符> [<表名2>.]<列名2>
[<表名1>.]<列名1> BETWEEN [<表名2>.]<列名2> AND [<表名2>.]<列名3>
连接字段:连接谓词中的列名称
连接条件中的各连接字段类型必须是可比的,但名字不必相同
等值连接查询:连接运算符为=
例:查询每个学生及其选修课程的情况
语法:SELECT Student.*, SC.*
FROM Student,SC
WHERE Student.Sno=SC.Sno
/* 将Student与SC中同一学生的元组连接起来 */
自然连接查询:若在等值连接中把目标列中重复的属性列去掉则为自然连接,
例:查询每个学生的学号、姓名、性别、出生日期、主修专业及该学生选修课程的课程号与成绩
语法:SELECT Student.Sno,Sname,Ssex,Sbirthdate,Smajor,Cno,Grade
FROM Student,SC
WHERE Student.Sno=SC.Sno;
其中:
Sname,Ssex,Sbirthdate,Smajor,Cno和Grade属性列在Student表与SC表中唯一,引用时可以去掉表名前缀
Sno在两个表都出现,因此SELECT子句和WHERE子句在引用时必须加上表名前缀
复合条件连接查询:WHERE子句是由连接谓词和选择谓词组成的复合条件
例:查询选修81002号课程且成绩在90分以上的所有学生的学号和姓名
语法:SELECT Student.Sno,Sname
FROM Student,SC
WHERE Student.Sno=SC.Sno AND /*连接谓词 */
SC.Cno='81002' AND SC.Grade>90; /*其他选择条件*/
自身连接查询:一个表与其自己进行连接
- 需要给表起别名以示区别
- 由于所有属性名都是同名属性,因此必须使用别名前缀
例:查询每一门课的间接先修课(即先修课的先修课)
语法:SELECT FIRST.Cno,SECOND.Cpno
FROM Course FIRST, Course SECOND
WHERE FIRST.Cpno=SECOND.Cno and SECOND.Cpno IS NOT NULL;
多表连接查询:两个以上的表进行连接
例:查询每个学生的学号、姓名、选修的课程名及成绩。
语法:SELECT Student.Sno,Sname,Cname,Grade
FROM Student,SC,Course
WHERE Student.Sno=SC.Sno AND SC.Cno=Course.Cno;
1.3嵌套查询
嵌套查询概述
- 在数据库操作中,一个SELECT-FROM-WHERE语句称为一个查询块
- 将一个查询块嵌套在另一个查询块的WHERE子句或HAVING短语的条件中的查询称为嵌套查询
例:SELECT Sname /*外层查询或父查询*/
FROM Student
WHERE Sno IN (SELECT Sno /*内层查询或子查询*/
FROM SC
WHERE Cno= ‘ 81003 ');
- 上层的查询块称为外层查询或父查询
- 下层的查询块称为内层查询或子查询
- SQL语言允许多层嵌套查询,即一个子查询中还可以嵌套其他子查询
- 子查询的限制:SELECT语句不能使用ORDER BY子句
不相关子查询:子查询的查询条件不依赖于父查询,由里向外逐层处理。
相关子查询:子查询的查询条件依赖于父查询,
- 首先取外层查询中表的第一个元组,根据它与内层查询相关的属性值处理内层查询,若WHERE子句返回值为真,则取此元组放入结果表
- 然后再取外层表的下一个元组
- 重复这一过程,直至外层表全部检查完为止
带有IN谓词的子查询
例:查询与“刘晨”在同一个主修专业的学生学号、姓名和主修专业
此查询要求可以分步来完成
语法:SELECT Sno,Sname,Smajor
FROM Student
WHERE Smajor IN (SELECT Smajor
FROM Student
WHERE Sname='刘晨’);
带有比较运算符的子查询
当能确切知道内层查询返回单值时,可用比较运算符(>,<,=,>=,<=,!=或< >)
例1:由于一个学生只可能在一个系学习,则可以用 = 代替IN
语法:SELECT Sno,Sname,Smajor
FROM Student
WHERE Smajor = (SELECT Smajor
FROM Student
WHERE Sname= '刘晨');
例2:找出每个学生超过他选修课程平均成绩的课程号
语法:SELECT Sno, Cno
FROM SC x
WHERE Grade >=(SELECT AVG(Grade)
FROM SC y
WHERE y.Sno=x.Sno);
带有ANY(SOME)或ALL谓词的子查询
例:查询非计算机科学技术专业中比计算机科学技术专业任意一个学生年龄小(出生日期晚)的学生的姓名、出生日期和主修专业
语法:SELECT Sname,Sbirthdate, Smajor
FROM Student
WHERE Sbirthdate > ANY (SELECT Sbirthdate
FROM Student
WHERE Smajor= ‘计算机科学与技术')
AND Smajor <> ‘计算机科学与技术 ’; /*父查询块中的条件 */
通过对ANY,ALL和聚集函数等的不同使用,通常可以实现同样的功能:
带有EXISTS谓词的子查询
- 带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”
- 由EXISTS引出的子查询,其目标列表达式通常都用 * ,因为带EXISTS的子查询只返回真值或假值,给出列名无实际意义
例:查询所有选修了81001号课程的学生姓名。
语法:SELECT Sname
FROM Student
WHERE EXISTS (SELECT *
FROM SC
WHERE Sno=Student.Sno AND Cno='81001’);
1.4集合查询
集合操作的种类
- 并操作UNION
- 交操作INTERSECT
- 差操作EXCEPT
参加集合操作
- 各查询结果的列数必须相同;
- 对应项的数据类型也必须相同
例:查询计算机科学与技术专业的学生及年龄不大于19岁的学生
语法:SELECT * FROM Student WHERE Smajor='计算机科学与技术'
UNION
SELECT * FROM Student
WHERE (extract(year from current_date) - extract(year from Sbirthdate)) <=19;
例2:查询2020年第2学期选修了课程81001或者选修了课程81002的学生
语法:SELECT Sno
FROM SC
WHERE Semester='20202' AND Cno='81001'
UNION
SELECT Sno
FROM SC
WHERE Semester='20202' AND Cno='81002';
例3:查询计算机科学与技术专业的学生与年龄不大于19岁的学生的交集
语法:SELECT *
FROM Student
WHERE Smajor='计算机科学与技术'
INTERSECT
SELECT *
FROM Student
WHERE(extract(year from current_date)-extract(year from Sbirthdate) ) <=19;
小结
在本节内容中,我们学习了SQL的查询语句,包括单表查询、连接查询、嵌套查询和集合查询,下一节我们将讲述SQL的更新和视图语句。
标签:管理系统,Sno,数据库,查询,Student,SQL,SC,WHERE,SELECT From: https://blog.csdn.net/n04j04h06/article/details/144474971