目录
查询语句结构
SELECT <列名> FROM <表名>
[WHERE <行选择条件>]
[GROUP BY <分组依据列>]
[HAVING <组选择条件>]
[ORDER BY <排序依据列>]
1、单表查询
(1)查询指定的列
例 查询全体学生的学号和姓名
SELECT Sno, Sname FROM Student
(2)查询全部列
例 询全体学生的的详细信息
SELECT * FROM Student
(3)查询经过计算的列
例 查询全体学生的姓名及出生年份
SELECT Sname, 2016 - Sage FROM Student
列别名
经过计算的列、常量列的显示结果都没有列名(无列名),通过为列起别名的方法可以指定或改变查询结果显示的列名,这个列名就称为列别名。
指定列别名语法格式
>列名 | 表达式 [AS] 列别名
或
列别名 = 列名 | 表达式
改写后
SELECT Sname AS 姓名, 2016 - Sage AS 年份 FROM Student
2、选择表中的若干元组
(1)消除取值相同的行(DISTINCT)
DISTINCT关键字可以去掉查询结果中的重复行。
例 在选课表中查询有哪些学生选修了课程,列出选课学生的学号
SELECT DISTINCT Sno FROM SC
(2)查询满足条件的元组(WHERE)
1)比较大小
例 查询计算机系全体学生的姓名
SELECT Sname FROM Student WHERE Sdept = '计算机系'
例 查询年龄小于20的学生姓名和年龄
SELECT Sname, Sage FROM Student WHERE Sage < 20
例 查询考试成绩有不及格的学生的学号
SELECT DISTINCT Sno FROM SC WHERE Grade < 60
2)确定范围(BETWEEN … AND)
BETWEEN … AND
格式
列名 | 表达式 [NOT] BETWEEN 下限值 AND 上限值
例 查询年龄在20~23岁之间的学生的姓名、所在系和年龄
SELECT Sname, Sdept, Sage FROM Student
WHERE Sage BETWEEN 20 AND 23
日期类型的常量要用单引号括起来,而且年、月、日之间通常永分隔符隔开,常用的分隔符有“/”和“-”。
例 查询2014年6月出版的全部图书的详细信息
SELECT * FROM 图书表
WHERE 出版日期 BETWEEN '2014/6/1' AND '2014/6/50'
3)确定集合(IN)
IN的语法格式
列名 [NOT] IN (常量1,常量2,...,常量n)
例 查询信息系、数学系和计算机系学生的姓名和性别
SELECT Sname, Ssex, FROM Student
WHERE Sdept IN ('信息系', '数学系', '计算机系')
4)字符串匹配(LIKE)
LIKE运算符的一般形式:
列名 [NOT] LIKE <匹配串>
- _:匹配任意一个字符
- %:匹配0个或多个字符
- [ ]:匹配[ ]中的任意一个字符
- [ ^ ]:不匹配[ ]中的任意一个字符。
例 查询“张”的学生的详细信息
SELECT * FROM Student WHERE Sname LIKE '张%'
例 查询学生表中姓“张”、姓“李”和姓“刘”的学生详细信息
SELECT * FROM Student WHERE Sname LIKE '[张李刘]%'
例 查询名字中第2个字为“小”或“大”的学生姓名和学号
SELECT Sname, Sno FROM Student WHERE Sname LIKE '_[小大]%'
5)涉及空值的查询
格式:
列名 IS NULL
例 查询没有考试成绩的学生的学号和相应的课程号
SELECT Sno, Cno FROM SC WHERE Grade IS NULL
6)多重条件查询
AND、OR
AND的优先级高于OR
例 查询计算机系年龄在20岁以下的学生姓名
SELECT Sname FROM Student
WHERE Sdept = '计算机系' AND Sage < 20
例 查询计算机系和信息系年龄大于等于20的学生姓名、所在系和年龄
SELECT Sname, Sdept, Sage FROM Student
WHERE (Sdept = '计算机系' OR Sdept = '信息系')
AND Sage >= 20
3、对查询结果进行排序(ORDER BY)
排序子句的格式为:
ORDER BY <列名> [ASC | DESC ] [ ,... n]
ASC表示按列值进行升序排序
DESC表示按列值进行降序排序
默认升序
例 查询全体学生详细信息,并将结果按年龄升序排序
SELECT * FROM Student ORDER BY Sage ASC
例 查询全体学生的信息,嘻哈寻结果按所在系的系名升序排列,同一系的学生按年龄降序排列
SELECT * FROM Student ORDER BY Sdept ASC, Sage DESC
4、聚合函数
聚合函数不能出现在WHERE子句中,除COUNT(*)在计算时不考虑空值外,其余聚合函数均会去掉空值后再计算。
1、COUNT(*):统计表中元组的个数
2、COUNT ( [ DISTINCT ] <列名> ):统计列的非空列值个数,DISTINCT表示去掉列的重复值后再统计
3、SUM ( < 列名 > ):计算列的值的和(数值型列)
例 统计选修了课程的总人数
4、AVG(<列名>):计算列的平均值(数值型列)
例 计算“c01”课程的考试平均成绩
5、MAX(<列名>):返回列的最大值
6、MIN(<列名>):返回列的最小值
1、COUNT
- COUNT(*):统计表中元组的个数
- COUNT ( [ DISTINCT ] <列名> ):统计列的非空列值个数,DISTINCT表示去掉列的重复值后再统计
例 统计学生总人数
SELECT COUNT(*) FROM Student
例 统计选修了课程的学生人数
SELECT COUNT (DISTINCT Sno) FROM SC
2.SUM
SUM ( < 列名 > ):计算列的值的和(数值型列)
例 统计选修了课程的总人数
SELECT COUNT (DISCOUNT Sno) FROM SC
例 统计“9512101”学生的选课门数和考试总成绩
SELECT COUNT(*) AS 选课门数,SUM(Grade) AS 总成绩
FROM SC WHERE Sno = '9512101'
3. AVG
AVG(<列名>):计算列的平均值(数值型列)
例 计算“c01”课程的考试平均成绩
SELECT AVG(Grade) AS 平均成绩 FROM SC WHERE Cno = 'c01'
4. MAX / MIN
MAX(<列名>)返回列的最大值
MIN(<列名>):返回列的最小值
例 查询“c01”课程的考试最高分和最低分
SELECT MAX(Grade) AS 最高分,MIN(Grade) AS 最低分
FROM SC WHERE Cno='c01'
例 查询“9512101”学生的选课门数、已考试课程门数以及考试最高分、最低分、平均分
SELECT COUNT(*) AS 选课门数,COUNT(Grade) AS 考试门数,
MAX(Grade) AS 最高分,MIN(Grade) AS 最低分,
AVG(Grade) AS 平均分
FROM SC WHERE Sno = '9512101'
5、对查询结果进行分组统计
1、GROUP BY
GROUP BY <分组依据列> [ , ... n ]
- 分组依据列不能是列别名
- 带有GROUP BY字句的SELECT语句的查询列表中只能出现分组依据列或聚合函数,因为分组后每个组只返回一行结果
例 统计每门课程的选课人数,列出课程号和选课人数
SELECT Cno as 课程号,COUNT(Sno) as 选课人数
FROM SC GROUP BY Cno
例 带WHERE子句的分组。统计每个系的女生人数。
SELECT Sdept,Count(*) 女生人数 FROM Student
WHERE Ssex = '女'
GROUP BY Sdept
例 按多列分组。统计每个系的男生人数和女生人数,以及男生的最大年龄和女生的最大年龄。结果按系名的升序排序。
SELECT Sdept, Ssex, Count(*) 人数,Max(Sage) 最大年龄
FROM Student
GROUP BY Sdept, Ssex
ORDER BY Sdept
2、HAVING
HAVIGN子句用于对分组后的结果再进行筛选
- 它的功能有点像WHERE子句,但它用于组而不是单个记录。
- 在HAVIING子句中可以使用统计函数,但在WHERE子句中则不能。
- HAVING通常与GROUP BY子句一起使用。
例 查询选修了三门以上课程的学生的学号和选课门数。
SELECT Sno, Count(*) 选课门数 FROM SC
GROUP BY Sno
HAVING COUNT(*) > 3
6、多表连接查询
1、内连接
内连接语法格式:
FROM 表1 [INNER] JOIN 表2 ON <连接条件>
连接条件语法格式:
[<表名1.>]<列名1> <比较运算符> [<表名2.>]<列名2>
当比较运算符为等号(=)时,称为等值连接,使用其他运算符的连接称为非等值连接。
例 查询每个学生及其选课的详细信息。
SELECT * FROM Student INNER JOIN SC ON Student.Sno = SC.Sno
这样会有重复列,改写去掉重复列
SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM Student JOIN SC ON Student.Sno = SC.Sno
为表指定别名
当为表指定了别名时,在查询语句中的其他地方,所有用到表名的地方都要使用别名,而不能再使用原表名。
例 查询计算机系学生的修课情况,要求列出学生的名字、所选的课程号和成绩。
SELECT Sname, Cno, Grade
FROM Student S JOIN SC ON S.Sno = SC.Sno
WHERE Sdept = '计算机系'
三表查询
例 查询“信息系”修了“计算机文化学”课程的学生信息,要求列出学生姓名、课程名和成绩
SELECT Sname,Cname,Grade
FROM Student s JOIN SC ON s.Sno = SC.Sno
JOIN Course c ON c.Cno = SC.Cno
WHERE Cname = 'VB'
2、自连接
通过为表取别名的方法实现自连接
例 查询与刘晨在同一个系学习的学生的姓名和所在系。
SELECT S2.Sname, S2.Sdept FROM Student S1 JOIN Student S2
ON S1.Sdept = S2.Sdept
WHERE S1.Sname = '刘晨'
AND S2.Sname !='刘晨'
3、外连接
外连接时只限制一张表中的数据必须满足连接条件,而另一张表重点数据可以不满足连接条件。
格式:
FROM 表1 LEFT | RIGHT [OUTER] JOUN 表2 ON <连接条件>
- “LEFT [OUTER] JOIN”称为左外连接
限制“表2”中的数据必须满足连接条件,而不管“表1”中的数据是否满足连接条件,均输出表1中的内容- “RIGHT [OUTER] JOIN”称为右外连接
限制“表1”中的数据必须满足连接条件,而不管“表2”中的数据是否满足连接条件,均输出表2中的内容
例 查询学生的选课情况,包括选了课程和没有选课程的学生,列出学号、姓名、课程号和成绩。
SELECT Student.Sno, Sname, Cno, Grade
FROM Student LEFT OUTER JOIN SC
ON Student.Sno = SC.Sno
7、使用TOP限制结果集
格式:
TOP n [ percent ] [ WITH TIES]
其中:
- n为非负整数
- TOP n表示取查询结果的前n行数据
- TOP n percent表示取查询结果的前n%行数据
- WITH TIES表示包括并列的结果
如果在TOP子句中使用了WITH TIES谓词,则要求必须使用ORDER BY子句对查询结果进行排序,否则会有语法错误。
例 查询年龄最大的三个学生的姓名、年龄及所在系。
SELECT TOP 3 Sname, Sage, Sdept
FROM Student
ORDER BY Sage DESC
若要包括年龄并列第3名的所有学生,可改写为:
SELECT TOP 3 WITH TIES Sname, Sage, Sdept
FROM Student
ORDER BY Sage DESC