数据查询功能查询功能是SQL按的核心功能,是数据库用的最多的操作,查询语句是SQL语句比较复杂的语句。以下查询用到的三张表如下所示:
Student表:

Sno Sname Ssex Sage Sdept
150752 孙兰昌 20 计算机系
150765 梁诗笛 19 计算机系

Course表:

Cno Cname Credit Semester
c01 高等数学 5 1
c02 数据结构 3 2

SC表:

Sno Cno Grade
150752 c01 90
150765 c02 88

查询语句的基本结构

查询语句的基本结构可描述为:

1
2
3
4
5
6
select <目标列名序列> --需要哪些列
from <数据源> --来自哪些表
[where <检索条件表达式>] --根据什么条件
[group by <分组依据列>]
[having <组提取条件>]
[order by <排序依旧列>]

单表查询

distinct去重

SQL语言中的distinct关键字可以去掉查询结果的重复行,distinct放在select的后边、目标列名的前边。例如:
select distinct Sno from SC

[not] in_%[]匹配、escape转义、order by排序

  1. in确定集合
    in确定某个集合,not in不在某个集合,例如:
    • select Sname, Ssex from Student where Sdept in ('计算机系', '数学系')此查询等价于 select Sname, Ssex from Student where Sdept='计算机系' or Sdept='数学系'
    • select Sname, Ssex from Student where Sdept not in ('计算机系', '数学系')此查询等价于 select Sname, Ssex from Student where Sdept!='计算机系' and Sdept!='数学系'
  2. 字符串匹配
    一般形式为:列名 [not] like <匹配串>
    1. _:匹配任意一个字符
    2. %:匹配0个或多个字符
    3. []:匹配[]中的任意一个字符。如[aeiou]匹配a、e、i、o、u中的任何一个。对于连续的字母匹配,例如[abcd]可以简写[a-d]
    4. [^]:不匹配[]中的任何一个字符。如[^abc]表示不匹配a、b、c。对于连续的字母可以简写例如[^a-d]
  3. escape转义字符匹配
    语法格式:escape 转义字符
    例如: where field like '%30\%%' escape '\'
  4. 对查询结果进行排序
    排序语法格式: order by <列名> [asc | desc]
    asc:升序排序,desc:降序排序。如果指定多个列排序,则按照列的先后顺序排序,即最前面的优先级最高。
  5. 使用聚合函数汇总数据
    • count([distinct] <列名>):统计本列非空列值个数。
    • sum() ave() min() max()功能类似

group by分组

语法:group by [分组依据列] [having <组约束条件>]
SQL先执行where后执行group by再执行having,建议在所有分组之前进行的搜索条件放在where中,分组之后的条件搜索放在having中更为高效。
Note:
查询年龄小于20学生人数:select Sdept, count(*) from Student where age < 20 group by Sdept,而不能写成:select Sdept, count(*) from Student group by Sdept having Sage < 20,因为在分组之后只保留分组依据列以及聚合函数,因为执行到having时已经没有Sage列了。

多表连接查询

内连接

使用内连接时,如果两个表的相关字段满足连接条件,则从两个表提取数据并组合成新的记录。
语法格式:from table1 [inner] join table on <连接条件>
例如:select * from studnet inner join SC on Studnet.Sno = SC.Sno

自连接

在自连接时一定要有别名。
例如:查询与操作系统学分相同的课程的课程名和学分。select C1.Cname, C2.Credit from Course C1 join Course C2 on C1.Credit = C2.Credit where C2.Cname = '操作系统'

外连接

查找不满足条件的记录。left以左表为基础对右表进行筛选,right类似。
语法:from table1 left | right [outer] join table2 on <连接条件>
例如:查询学生的选课情况,包括选了课程的学生和没有选课程的学生,列出学号、姓名、课程号和成绩。select Studnet.Sno, Sname, Cno, Grade from Student left outer join SC on Student.Sno = SC.Sno

使用TOP限制结果集

语法:top n [percent] [with ties]
一般与order by同时使用。
其中:

  • n为非负整数
  • top n表示取查询的前n行数据
  • top n percent:表示取查询结果的前n%行数据
  • with ties:包括并列的结果
    例如:查询年龄最大的三个学生的信息,包括并列的情况。select top 3 with ties * from Student order by Sage desc

    子查询

    SQL语言中,一个select-from-where语句称为一个查询块。一个查询块嵌入了另外一个selectinsertupdatedelete则称为子查询或内层查询。

    集合测试

    语法:where 表达式 [not] in (子查询)
    例如:
  1. 查询与小明同在一个系学习的学生。select * from Student where Sdept in (select Sdept from Student where Sname='小明')
  2. 查询选了c02课程的学生。select * from Student where Sno in (select Sno from SC where Cno='c02') and,此查询也可以用多表连接查询实现:select * from Student as S join SC on S.Sno==SC.Sno where Sdept='计算机系' and Cno='c02'

    比较测试

    语法:where 表达式 比较运算符 (子查询)
    其中比较运算符有:= <> < > <= >=
    例如:
  • 查询考试成绩高于平均成绩的学生:select * from student from SC group by Sno having AVG(Grade) > (select AVG(Grade) from SC)

    集合测试和比较测试都是先执行子查询,在执行外层查询,子查询只执行一次且不依赖于外层查询,这样的查询称为不相关子查询嵌套子查询

存在测试

语法:where [not] exists (子查询)

  1. 存在测试先执行外层查询,后执行子查询;子层查询的次数由外层查询结果决定。
  2. 存在测试只返回真值或假值,所以在子查询中指定列名没有意义,通常用select *代替。
    例如:查询选修了c01课程的学生:select * from Student where exists (select * from SC where Sno = Student.Sno and Cno = 'c01')