数据查询数据查询
模块五




单表查询
多表查询
子 查 询
简单查询 Select… From…
条件查询 where…
分类查询 group by… having…
多表连接查询
多表连接综合查询
简单子查询
操作符子查询
数据查询模块能力面的形成
任务一 Select… From… ( 2学时)
1,从学生基本信息表中查询所有记录。在 【 查询分析器 】 输入如下代码,
选中后按 F5键运行,如图 1所示。
图 1
注:星号( *)用于代指所查询表中的所有字段(列)。
简单查询
2,查询学生基本信息表中的学生姓名、班级编号。
select xm,bjbh from stu
注:语句中使用的标点符号必须采用英文格式。
3,查询语句的其它用法
a,将查询字段改名显示。在 【 查询分析器 】 中如下输入代码,运行
如图 2所示。
图 2 图 3
通过 ? as”,以 ? 姓名 ? 为字段名而不再是 ? xm”显示 stu表中的字段名

b,作为一般计算器使用,即不使用 From语句。如
Select 1+2 as 加法 --以 ? 加法 ? 为字段名显示结果,3
注:像这种不属于所查询表中的字段如果不通过 ? as”指定别名,则
结果中将提示 ? 无列名 ? 。如图 3所示。
c,查询字段运算结果后的结果。在查询分析器输入如下代码,将显示平时
成绩和期末成绩各占 40%和 60%作为总成绩的结果。 运行如图 4所示。
注:几个常用函数:
·Getdate()。返回系统的当前日期。如:
select getdate()
显示系统当前时间:
2005-06-12 16:39:14.810
·Datepart()。以整数形式返回日期中的
指定部分。如:
select datepart(month,getdate()) as ‘月份 ‘
--显示当前日期中的 ? 月 ?, 6
·Substring()。返回指定字符串中指定位置的子串。如:
Select Substring(xh,9,12) as 学号 from stu
返回 stu表中学生号中从第 9个字符开始、第 12个字符结束的字符串,1001
更多函数请参阅查询分析器的帮助文件。
图 4
d,去掉重复记录。如:
Select distinct bjbh from stu
返回 stu表中所有的班级编号(无重复)。
e,对查询结果进行排序。如:
select xh,xm,zcj from stu order by xh desc
按学号降序显示 stu表中的学号、姓名、成绩。如图 5所示。
图 5
注,desc按降序排序,asc按升序排序。
f,查询限定个数记录。
Select top 5 xm from stu
查询 stu表中前 5个学生姓名。
注,top 后的数值限定返回记录的个数,如果数值后加上 percent,则指示百分
值。如,select top 5 percent * from stu返回 stu表中前 5%个学生记。
g,Case函数查询。在查询分析器输入如下代码,运行结果如图 6所示:
select xh,
成绩等级 =case
when qmcj <60 then ’不及格 ’
when qmcj >=60 and qmcj<70 then ‘及格 ’
when qmcj >=70 and qmcj <80 then ‘中 ’
when qmcj >=80 and qmcj <90 then ‘良 ’
else ‘优 ’ end,
qmcj from xk
图 6
从 xk表查询所有学生的
学号、成绩等级(新字段)
和期末成绩,成绩等级根据
期末成绩按分数段划分。
注,case函数用于计算多个条件列表并返回相应的值。 Case具有以下两种
语法格式:
·简单函数。将某个表达式的值与一组简单表达式的值进行比较以返回
结果。如,
case qmcj
when 60 then ‘六十 ’
when 70 then ‘七十 ’
end
将 qmcj的值分别与 60,70比较是否相等,并跟据比较返回 ? 六十 ? 或 ? 七
十 ?, 若都不匹配,有没有 else语句,则返回空值。
这种用法要求 case后先跟上一个具体的表达式(或字段名),再用
该表达式的值与每个 when语句中的单个值进行比较(是否相等),不
能使用任何关系或逻辑等运算符。
· 搜索函数。计算一组布尔表达式以确定结果。如本例。
另外,Case函数必须以 end结束,且 end后还可以用逗号连接下一个
要查询的字段; Else是可选语句。
实训一
1.查询 stu表中的 xm,xh,bjbh,并将列名显示为姓名、学号、班级编号。
2.查询 stu表中的 xm,xb,xb根据值男或女分别改为 m,f并按 xm降序显示。
3.查询 xk表中的 xh,kch,并将出生日期经过操作后以新字段 ? 年龄 ? 显示。
返回 退出返回 退出
任务二 条件查询 where… ( 1学时)
1,关系条件
Select * from stu where xm=’李春华 ’
查询名为 ? 李春华 ? 的学生的所有信息。又如:
Select * from stu where zcj>200
查询总成绩超过 200分的所有学生信息。
注:关系运算符包括 =,<,>,<>(或 !=),<=(或 !>),>=( !<)。
又如:
Select * form stu where csrq!< '12/31/86' and
csrq <='12/31/88'
查询出生日期在 86年 12月 21日和 88年 12月 21日之间的学生记录。
2,逻辑条件
select xm,xb from stu where bjbh=’ 041022021’
查询 stu表中班级编号为 ? 041022021”的学生姓名和性别。
注:逻辑运算符包括 not,and,or。
3,模式匹配条件
select xh,xm,xb from stu where name like ‘张 %’
查询所有姓 ? 张 ? 的学生学号、姓名和性别。
注:模式字符串通配符含义和示例对照表,
通配符 描述 示例
%
包含零个或更多字符
的任意字符串。
WHERE name like'%玉 %' 将查找处
于书名任意位置包含 ? 玉 ? 的所有
姓名。
_
(下划线)
任何单个字符。 WHERE name like '_伟 ' 将查找以
? 伟 ? 结尾的所有 2 个字的名字。
[ ]
指定范围 ([a-f]) 或
集合 ([abcdef]) 中
的任何单个字符。
WHERE name like '[C-P]arsen' 将
查找以 arsen 结尾且以介于 C 与 P
之间的任何单个字符开始的姓名,
例如,Carsen,Larsen,Karsen 等。
[^]
不属于指定范围 ([a-
f]) 或集合
([abcdef]) 的任何单
个字符。
WHERE au_lname like 'de[^l]%'
将查找以 de 开始且其后的字母不
为 l 的所有作者的姓氏。
与 Like功能相反的是 not like。如:
Select * from stu where xm not like ‘张 %’
查询 stu表中不姓 ? 张 ? 的学生记录。
4,范围条件
select * from xk where kccj between 60 and 90
从 xk表查询课程成绩在 60至 90之间的所有记录。
注,between…and… 实际上相当于 …>=… and …<=… 。如上例
等价于:
select * from xk where kccj>=60 and kccj<=90
5,集合条件
Select * from xk where kccj in (70,80,90,100)
从 xk表查询成绩为 70,80,90,100的所有记录。
注,in后可以跟任意集合,如字符串集合( ’ a’,’b’,’m’,’n’,’f’)。
与 in含义相反的是 not in。如:
Select * from stu where xm not in (‘兰飞 ’,’余杰 ’,’王燕 ’ )
查询姓名不是 ? 兰飞 ?, ? 余杰 ?, ? 王燕 ? 的学生记录。
有时 in等价于 or的功能。如上例等价于,
Select * from xk where kccj=70 or kccj=80 or
kccj=90 or kccj=100
可以看出,对于比较同一个字段与若干个值中的某一个是否相等
时,使用 in更为简洁。
In 还能与子查询配合使用,具体方法见本章课题 ? 子查询 ? 之 ? 集

查询 ? 。
实训二
1.查询 stu表中 mc在前三名的所有学生的记录。
2.查询 stu表中 bjbh为 041022051,041022061的所有学生姓名。
3.查询 xk表中学号为 041022021001的学生所选科目课程号、成绩。
返回 退出返回 退出
任务三 分类查询 group by… having… ( 1学时)
1,分类查询。适用于需要对某些字段进行分门别类的情况。如:
Select bjbh from stu group by bjbh
将 stu表中的记录按班级编号分类,每个班级编号只显示一个。
注:上例结果跟 select distinct bjbh from stu显示的一样,但 group
by还具有分类的功能。
group by… 子句用于将一列或多列进行分组,分组后的结果中每条
重复的记录只显示一行。又如:
select bjbh,xb from stu group by bjbh,xb
按照班级编号和性别进行分类,显示每个班级编号和对应性别,如
图 7所示。
图 7
分组时,select 语句中不能包括未出现在 group by语句中
的字段(聚集函数除外)。如,
select bjbh,xm from stu group by bjbh
是错误的。
但出现在 group by 中的字段名,可以不出现在 select语句
中,分组时将隐含包括未出现的字段记录。
如,select bjbh from stu group by bjbh,xb
显示结果中每个班级编号有两条记录,如图 8所示,因为每个
班级隐含包括男女两种性别,只是性别字段未显示而已。
图 8
2,聚合查询。适用于对表中数据进行份类统计的情况。如:
select bjbh,count(*) from stu group by bjbh
按班级编号统计每个班的人数,如图 9所示。又如:
select bjbh,xb,count(*) as 人数 from stu
group by bjbh,xb
按班级编号统计每个班的男女人数,如图 10所示,注意统计列
以 ? 人数 ? 命名。
图 9 图 10
注:常用的聚集函数参照表:
又如:
Select bjbh,avg(zcj) as 平均成绩 from stu group by bjbh
查询每个班的班级编号和平均分。如图 10所示。
聚合函数 描述
AVG(expr) 列值的平均值。该列只能包含数字数据。
COUNT(expr),
COUNT(*)
列值的计数(如果将列名指定为 expr)或是表
或组中所有行的计数(如指定 *)。 COUNT(expr)
忽略空值,但 COUNT(*) 在计数中包含空值。
MAX(expr) 列中最大的值(文本数据类型中按字母顺序排在
最后的值)。忽略空值。
MIN(expr) 列中最小的值(文本数据类型中按字母顺序排在
最前的值)。忽略空值。
SUM(expr) 列值的合计。该列只能包含数字数据。
图 11 图 12
3,条件查询。 Having可用于指定组或聚合的搜索条件。如:
select bjbh,xb,count(*) as 人数 from stu
group by bjbh,xb
having count (*)>3 and xb=’男 ’
查询 stu表中男生人数超过 10人的班级编号、男生人数,如图 12所示。
注,Having通常与 Group by子句一起使用。如果不使用 Group by子
句,Having 的功能与 Where子句一样。
聚合函数的比较不能写在 where语句中。如 where count(*)=10
是不正确的。
实训三
1.查询课程编号 kcbh为 010920001成绩最高分。
2.查询每门课程的课程号、最低分。
3.查询被 50名以上学生选修了的课程名、选课人数。
返回 退出返回 退出
任务一 表连接查询( 1学时)
1,简单表连接 from
Select xm,kcbh,kccj from stu,xk where stu.xh=xk.xh
从 stu表和 xk表查询每个学生每门课的成绩。如图 13所示。
注:要指明两张表通过哪个字段进行连接,
否则连接时两表每行都互相连接;
此外,要使用多个表都共有的字段时,
必须指名来自哪张表(如 stu.xh),
如果表名太复杂,可以在 form语句中通过
在表名后加空格在加别名来降低编写的复
杂度,
如:
Select a.xh,xm,kch,kccj from stu a,xk 图 13
2,查询 ? 李智 ? 选修的课程名
select kcm
from stu,xk,kc
where stu.xh=xk.xh and xk.kch=kc.kch
注:在表连接中,还涉及到自连接( from 后跟的几张表都是同一张表,
通过不同的别名区分)、外连接等方式(条件中在表达式前加上 *号确
保连接的表没有漏掉的记录),由于较少使用,故此略过,有兴趣的同
学请参考查询分析器的帮助文件学习。
实训一
1.查询 ? 文琴 ? 选修的课程名、成绩。
2.查询 ? 03商务 1班 ? 的所有选课名称。
返回 退出返回 退出
任务二 表连接综合查询( 1学时)
1.查询 ? 041022021”班高等数学的平均分。结果如图 14所示。
Select avg(zcj) From stu,xk,kc
Where stu.bjbh=’041022021’ and stu.xh=xk.xh and
kc.kcmc=’高等数学 ’ and xk.kcbh=kc.kcbh
2.统计每门课的选课门数超过 20人的课程名和选课人数。结果
如图 15所示。
select kcmc,count(*) from kc,xk
where kc.kcbh=xk.kcbh
group by kcmc
having count(*)>10
图 14 图 15
实训二
1.查询平均分在 90以上的学生姓名、平均分。
2.查询计算机软件班所选课程名称。
返回 退出返回 退出
任务一 简单子查询( 1学时)
1.查询 xk表中姓名为 ? 李春华 ? 的同学所有课程的平均分。在查询分析器如
下输入代码,结果如图 16所示。
select avg(kccj) from xk where xh=(select xh
from stu where xm=’李春华 ’ )
由于姓名和成绩分别属于两张表,若采用表连接也完全可以达到要求。
使用子查询时,先从 stu表找到 ? 李春华 ? 对应的学号,在从 xk表查询该学号
对应的平均成绩,这比直接使用表连接要直观的多。
注:子查询可以理解为在查询语句中再次使用 select语句的查询。在查询
语句任何可以使用表达式的地方都可以使用子查询。子查询可以嵌套使用。
图 16
2.查询所有班级总成绩的最高分
select max(总成绩 ) as 最高成绩
from (Select bjmc as 班级名称,sum(zcj) as 总成绩
From stu,bj
Where stu.bjbh=bj.bjbh
Group by bjmc) a
注:此时子查询用在了 form子句,把结果当作一张表用于提取信息,与
后下一专题讲到的视图类似。这种时候必须在子查询后跟上别名,否则
编译无法通过。如上例子查询的别名就是 a。
实训一
1.查询选修了高等数学的学生姓名。
2.查询所有班级中学生总分最高的班级名称。
返回 退出返回 退出
任务二 操作符子查询( 1学时)
1,In。查询学号为 20041010的同学所选课程的课程名。结果如图 17所示
select kcmcc from kc
where kcbh in (select kcbh from xk
where xh=’ 041022021003’)
图 17
每个同学选修的课程可能有多门,所以当查询课程名时,条件中的课
程号应该在一个集合内而不是单个值,故采用 in 子句。
注,in 可用于判定是否在一个集合之内。与此相反的是 not in(不在指定
集合)。
2,Exists。从 stu表中查询选修了任何课程的学生记录:
select * from stu
where exists (select * from xk where stu.xh=xk.xh)
即只要该学号在 xk中存在记录,则说明该学生选修了课程。
注:区分以下代码:
Select * from stu where exists(select * from xk)
如果 xk中有任何记录存在,就查询出 stu表中的所有数据。
3,Any。查询比 2000002班某个同学总成绩高的学生姓名:
select xm from stu where zcj> any (select zcj from stu
where bjbh=’200002’)
注:这里使用 any表示比结果集中 ? 某一个 ? 值大即满足条件。
与此对应的是 All,表示 ? 比所有的都 ? 。
4.相关子查询。查询总成绩高于本班平均总成绩的学生姓名。
Select xm,bjbh,zcj from stu a where zcj>(select avg(zcj)
from stu where a.bjbh=bjbh group by bjbh)
注:像这种依赖了主查询获取比较条件值的子查询称为 ? 相关子查 ? 。
上例中,学生成绩是否高于本班平均分要依赖该生所在的班级编号
才能计算得出。
实训二
1.查询 ? 李春华 ? 同学未选修的课程名。
2.查询总成绩高于 041022071班总成绩的班级编号和总成绩。
返回 退出返回 退出