Select tblStudent.Stud_Id , Stud_Name , Course_Id , Score From tblStudent
Left Join tblScore On tblStudent.Stud_Id=tblScore.Stud_Id
执行语句后的查询结果如图5-2所示(图5.2中的前4条记录是已选课学生的信息,后4条记录显示的是没有选课的学生信息)。
图5-2 在成绩表中用左外连接显示所有学生选课信息
3.自连接
连接操作不仅可以在不同的基表上进行,而且在同一张表内也可以进行自身连接。自连接可以看作一张表的两个副本之间进行的连接。在自连接中,必须为表指定两个别名,使之在逻辑上成为两张表。语句格式:
Select <别名1>.<列名1>,…,<别名1>.<列名n>,<别名2>.<列名1>,…,<别名2>.<列名m> From <表1> As <别名1>,<表1> As <别名2> Where <等值连接表达式>
【例5-16】职工档案表JA01的表结构如表5-3所示,表内容如表5-4所示。
表5-3 职工档案表JA01的表结构
序号 1 2 3 4 5 字段名 JA0101 JA0102 JA0103 JA0104 JA0105 含义 职工编码 职工姓名 性别码 部门编码 负责人编码 类型 宽度 小数 主键/外键 VARCHAR 10 P VARCHAR CHAR VARCHAR VARCHAR 10 1 10 10 F F F 父表/主键 GC01/GC0101 TB06/TB0601 JA01/JA0101 表5-4 职工档案表JA01的内容
JA0101(职工编码) JA0102(职工姓名) 3001 刘明强 3002 李明萍 4001 蒋明华 4002 翁明祥 JA0103(性别码) 1 2 2 1 JA0104(部门编码) 30 30 40 40 JA0105(负责人编码) 3001 3001 4001 4001 (1)用自连接方式显示职工负责人姓名,要求如图5-3所示。 Use Xsgl
Select A.JA0101 As '职工编码',A.JA0102 As '职工姓名',
- 146 -
A.JA0103 As '性别码',A.JA0104 As '部门编码',B.JA0102 As '负责人' From JA01 A
Join JA01 B On A.JA0105=B.JA0101
图5-3 职工编码与负责人编码进行自连接
(2)用自连接与内连接方式显示职工的性别、系部与负责人姓名,如图5-4所示。 Use Xsgl
Select A.JA0101 As '职工编码',A.JA0102 As '职工姓名', GC0102 As '性别',TB0602 As '所属部门',B.JA0102 As '负责人' from JA01 A
Join JA01 B On A.JA0105=B.JA0101 Join GC01 On A.JA0103=GC0101 Join TB06 On A.JA0104=TB0601
图5-4 用自连接与内连接方式显示职工的性别、系部与负责人姓名
4.交叉连接
交叉连接也叫非限制连接,它将两个表不加任何约束地组合在一起。在数学上,就是两个表的笛卡尔积。交叉连接后的结果集的行数是两个表的行数的乘积。在实际应用中,这种连接方式极少用到。
语句格式: Select <选择列表>
From <表1> Cross Join <表2>
【例5-17】将职工档案表JA01与系部TB06进行交叉连接。 Use Xsgl Select *
From JA01 Cross Join TB06
- 147 -
语句执行后如图5-5所示,查询结果共有4(JA01的行数)*10(TB06的行数)=40行。
图5-5 JA01与TB06的交叉连接
5.1.3 排序
排序是将数据表中的记录按指定列值或列组值升序或降序排列,语句格式如下。 Select <选择列名> From <表名>
Order By <列名或列号> [Asc | Desc] [,……] 说明:
(1)Asc为升序排序(默认值),Desc为降序排序。 (2)可对多达16个列执行Order By语句。
【例5-18】 对学生档案表XA01按照系部编码(升序)、班级编码XA0114(升序)与学号XA0102(降序)排序,显示系部名称、班级名称、学号与姓名。
Use Xsgl
Select TB0602 系部名称,TB0302 班级名称,XA0102 学号,XA0104 姓名 From XA01
Join TB03 On XA0114=TB0301 Join TB06 On TB0309=TB0601
Order By TB0601 Asc, TB0301 Asc, XA0102 Desc
5.1.4 分组统计查询
用户经常要对数据库中的数据进行统计汇总,为此,Select语句提供了Group By 子句用于分组统计,分组统计语句格式如下。
Select <分组字段>,<统计函数> From <表名> Where <条件表达式>
- 148 -
Group By <分组字段名> Having <条件表达式> Order By <排序字段名> [Asc | Desc] 说明:
(1)Select子句中的统计函数如表5-5所表示,同一个Select子句可包括多个统计函数。
表5-5 统计函数
统计函数 Sum(字段名) Avg(字段名) Min(字段名) Max(字段名) Count(字段名) 或Count(*) 对数值字段求和 对数值字段求平均值 求字段最小值 求字段最大值 统计记录行数 描述 (2)Group By <分组字段名> 表示,Select子句中的统计函数将按分组字段进行统计。若无Group By子句,则统计函数对整个数据表进行统计,即统计结果只有一条记录。
【例5-19】在学生档案表tblStudent与学生成绩表tblScore中完成如下统计任务。 ① 统计学生档案表tblStudent中的学生总人数。 Select Count(*) From tblStudent
语句执行后统计结果只显示一条记录,即学生总人数为:2459
② 在学生成绩表tblScore中,统计选修课程号='1004'的课程的选修平均成绩。 Select Avg(Score) From tblScore Where Course_Id='1004'
语句执行后统计结果只显示一条记录,即数学平均成绩为:72.32 ③ 计算课程号='1004'的课程的选修最高成绩、最低成绩和平均成绩。 Select Max(Score) AS Max, Min(Score) AS Min, Avg(Score) AS Avg From tblScore Where Course_Id='1004'
语句执行后的统计结果是最高分Max=99、最低分Min=0、平均分Avg=72.32。
(3)若对查询结果进行分组,则统计函数将作用于每一个组,即每一组都有一个函数值,显示多条记录。
(4)在Select子句中出现的“分组字段”必须出现在 “Group By”子句后面,且字段名相同。
(5)Having <条件表达式> 子句用于对分组字段进行条件检查,条件表达式中的字段只
- 149 -
能是Select子句中的“分组字段名”或“统计函数名”。
【例5-20】 按下列要求统计学生档案表XA01中各班学生人数。 ① 用班级编码XA0114作为分组字段,查询各班学生人数。 Use Xsgl
Select XA0114,Count(*) From XA01 Group By XA0114
用查询分析器执行语句,对同一班级编码的学生人数进行分组统计,统计结果分为两列,第一列显示班级编码,第二列显示该班学生人数,如图5-6(a)所示。此图只显示班级编号与该班学生人数,由于无班级名称,因此无法直观的知道各班学生人数。
② 通过班级编码表TB03与学生档案表XA01的内连接,用班级名称TB0302作为分组字段,查询各班学生人数。
Use Xsgl
Select TB0302 As '班级名称',Count(*) As '学生人数' From XA01
Join TB03 On TB0301=XA0114 Group By TB0302
用查询分析器执行语句的结果如图5-6(b)所示,此图能显示班级名称与该班学生人数。 ③ 通过班级编码表TB03与学生档案表XA01、系部编码表TB06的内连接,用系部名称TB0602、班级名称TB0302、系部编码TB0601作为分组字段,查询各班学生人数。查询结果按系部编码TB0601升序排序。
Use Xsgl
Select TB0602 As '系部名称',TB0302 As '班级名称',Count(*) As '学生人数' From XA01
Join TB03 On TB0301=XA0114 Join TB06 On TB0309=TB0601 Group By TB0602,TB0302,TB0601 Order By TB0601
用查询分析器执行语句后的结果如图5-6(c)所示,此图能显示系部名称、班级名称与学生人数。
- 150 -