数据查询.

数据查询是数据库中最常用的操作,SQL中提供SELECT语句,通过查询操作可以得到所需的信息。SELECT语句的一般格式如下所示,可以暂时跳过,通过例子对查询操作有了直观的认知之后再看一般格式会更有理解:

SELECT [ALL|DISTINCT][TOP N [PERCENT]|[WITH TIES]]
Col_1 AS Nickname_1,Col_2 AS Nickname_2,...,Col_n AS Nickname_n
FROM NAME_OF_TABLE AS Table_Nickname
WHERE CONDITION
GROUP BY Col_x [HAVING CONDITION]
ORDER BY Col_y [ASC|DESC]

我们需要注意,查询的结果依然是一个关系,也就是一个数据表。SELECT语句的执行过程是,根据WHERE子句的检索条件,从FROM子句指定的基本表中选取满足条件的元组,再按照SELECT子句中指定的列,投影到这些列上得到结果。如果当中还有GROUP BY Col_x子句,则将查询的结果按照Col_x中相同的值进行分组,如果GROUP子句之后还有HAVING CONDITON子句,则只会输出满足条件表达式的元组。如果最后还有ORDER BY Col_y子句,查询结果还要按照ORDER子句中Col_y的值以及后面[ASC]|[DESC]进行升序或降序排列。

单关系数据查询.

无条件查询.

无条件查询是指只包含SELECT...FROM...的查询,这种查询最简单,相当于只对关系进行投影操作。

【例】查询全体学生的学号、姓名和年龄。

SELECT SNo,SN,Age
FROM S

【例】查询学生的全部信息。

SELECT *
FROM S

我们在SELECT语句中使用【*】表示全部列,而不必一一写出。

【例】查询选修了课程的学生的学号。
由于会存在一个学生选修多门课的情况,所以学生选课表中会存在重复的学号记录,我们希望过滤掉重复的学号。

SELECT DISTINCT SNo
FROM SC

上述查询中,都是没有出现WHERE子句的无条件查询,也称作投影查询。但需要注意,在关系代数的定义中,投影操作是会自动消去重复行,而SQL中的查询语句只有在使用关键字DISTINCT的情况下才会消去重复行。另外,通过查询语句,我们可以控制结果中列名出现的顺序,并且可以通过关键字AS来指定别名用于显示时的可读性。

【例】查询全体学生的姓名、年龄和学号。

SELECT SN AS Name,Age,SNo
FROM S

其中Name作为SN的别名出现在查询结果中。

条件查询.

当要在表中找出满足某些条件的行时,则需要使用WHERE子句指定查询条件,WHERE子句中的查询条件常常通过三部分来描述:

  • 列名
  • 比较运算符
  • 列名、常数

常用的比较运算符如下所示:

sqlalchemy或条件查询_sqlalchemy或条件查询


给出几个例子来展示条件查询的代码:

【例】查询选修课程号为C1的学生的学号和成绩。

SELECT SNo,Score
FROM SC
WHERE CNo='C1'

【例】查询成绩高于85分的学生的学号、课程号和成绩。

SELECT SNo,CNo,Score
FROM SC
WHERE Score>85

【例】查询选修C1或C2且分数大于等于85分的学生的学号、课程号和成绩。

SELECT SNo,CNo,Score
FROM SC
WHERE (CNo='C1' OR CNo='C2') AND Score>=85

【例】查询工资在1000元到1500元之间的教师的教师号、姓名以及职称。

SELECT TNo,TN,Prof
FROM T
WHERE Salary BETWEEN 1000 AND 1500

注意!在SQL Server中BETWEEN...AND...是一个闭区间,而有些DBMS中这是一个开区间。

【例】查询工资不在1000元到1500元之间的教师的教师号、姓名以及职称。

SELECT TNo,TN,Prof
FROM T
WHERE Salary NOT BETWEEN 1000 AND 1500

【例】查询选修了C1或C2或C3的学生的学号、课程号和成绩。

SELECT SNo,CNo,Score
FROM SC
WHERE CNo IN ('C1','C2','C3')

【例】查询那些没有考试成绩的学生的学号和相应的课程号。

SELECT SNo,CNo
FROM SC
WHERE Score IS NULL

【例】部分匹配查询。以上的查询都是属于完全匹配查询,当不知到精确的值时,我们还可以使用LIKENOT LIKE进行模糊查询,也就是部分匹配查询。LIKE的一般格式为:

NAME_OF_ATTRIBUTE LIKE STRING

其中,NAME_OF_ATTRIBUTR必须是一个字符型的量,后面的字符串常量STRING中可以包含通配符,利用它们进行模糊匹配。一些常用的通配符及其含义如下所示:

  • 【%】代表0个或多个字符,例如ab%代表ab之后可以接任意字符串。
  • 【_】代表1个字符,例如a_b代表ab之间可以有一个字符。
  • 【[ ]】代表在某一范围内的字符,例如[0-9]代表0~9之间的字符。
  • 【[^ ]】代表不在某一范围内的字符,例如[^0-9]代表不在0~9之间的字符。

【例】查询所有姓张的老师的教师号和姓名。

SELECT TNo,TN
FROM T
WHERE TN LIKE '张%'

【例】查询姓名中第二个字是’力’的教师的教师号和姓名。

SELECT TNo,TN
FROM T
WHERE TN LIKE '_力%'

库函数.

SQL中提供了许多库函数,增强了基本检索能力,常用的一些库函数如下所示:

sqlalchemy或条件查询_库函数_02


【例】求学号为S1的学生的总分和平均分。

SELECT SUM(Score) AS TotalScore,AVG(Score) AS AverageScore
FROM SC
WHERE SNo='S1'

上述的代码中,as关键字之后的是列的别名,别名会显示在查询结果中,让用户有更好的体验。在查询中使用库函数时,通常需要给每一项内容加上别名,否则查询结果中就不会显示列名。并且注意:库函数SUM()AVG()只能对于数值型的数据使用。

【例】求选修C1课程的最高分、最低分以及极差。

SELECT MAX(Score) AS MaxScore,MIN(Score) AS MinScore,
	MAX(Score)-MIN(Score) AS Difference
FROM SC
WHERE CNo='C1'

【例】求计算机系学生的总数。

SELECT COUNT(SNo) AS TotalStudents
FROM S
WHERE Dept='计算机'

【例】求学校中共有多少个系。

SELECT COUNT(DISTINCT Dept) AS DeptNumber
FROM S

使用关键字DISTINCT之后表示消除重复行,如此一来就可以计算字段Dept不同值的数目。

【例】统计计算机系的学生总数,使用COUNT(*)函数。

SELECT COUNT(*) AS TotalStudents
FROM S
WHERE Dept='计算机'

COUNT(*)函数用于统计所有元组的个数不会消除重复行,也不允许使用关键字DISTINCT

分组查询.

GROUP BY子句可以将查询结果按照属性列或者属性列的组合(即分组依据),在行的方向上进行分组,每一个分组内部在分组依据的属性列组合上拥有相同的值。

【例】查询每个教师的教师号及其任课的门数。

SELECT TNo,COUNT(*) AS TeachNumber
FROM TC
GROUP BY TNo

GROUP BY子句按照TNo的值进行分组,所有具有相同TNo的元组被分到一个组里,而后对于分好的每一个组进行COUNT(*)函数的计算,就能统计出每个教师的任课门数。

【例】查询选修两门及以上课程的学生的学号和选课门数。

SELECT SNo,COUNT(*) AS ClassNumber
FROM SC
GROUP BY SNo
HAVING COUNT(*)>=2

GROUP BY子句按照SNo的值进行分组,所有具有相同SNo的元组被归为一组,在每一个组内进行COUNT(*)函数的计算,并且HAVING子句选择那些结果大于等于2的组。
总结来说,当一个SQL查询中同时包含WEHERGROUP BY以及HAVING子句时,其顺序就是我们列出的顺序。

排序.

当我们需要对查询结果进行排序时,应当使用ORDER BY子句,ORDER BY子句必须出现在其它所有的子句之后。并且我们可以指定排序的方式,ASC为升序,DESC为降序,默认时采用升序。

【例】查询选修C1课程学生的学号和成绩,按成绩的降序排列。

SELECT SNo,Score
FROM SC
WHERE CNo='C1'
ORDER BY Score DESC

【例】查询选修C2、C3或C4课程学生的学号、课程号和成绩,结果按学号升序排列,学号相同即同一个学生的信息再按成绩降序排列。

SELECT SNo,CNo,Score
FROM SC
WHERE CNo IN ('C2','C3','C4')
ORDER BY SNo ASC,Score DESC

注意,其中ORDER BY SNo ASC,Score DESC也可以写成ORDER BY SNo,Score DESC,因为默认情况下采用升序。