S1/C#语言和数据库技术基础/11-连接查询和分组查询

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了S1/C#语言和数据库技术基础/11-连接查询和分组查询相关的知识,希望对你有一定的参考价值。

分组查询

采用分组查询的T-SQL语句如下。

SELECT   CourseID,AVG(Score)   AS   课程平均成绩

FROM   Score

GROUP   BY   CourseID

(1)查询男女学生的人数各是多少

SELECT   COUNT(*)    AS   人数,SSex    FROM   Students

GROUP   BY   SSex

(2)查询每个年级的总人数

SELECT   COUNT(*)   AS   年级人数,SGrade   FROM   Students

GROUP   BY   SGrade

(3)查询每个科目的平均分,并且按照由高到低的顺序排列显示

SELECT   CourseID,AVG(Score)   AS   课程平均成绩    FROM   Score

GROUP   BY   CourseID

ORDER    BY   AVG(Score)    DESC

 

多列分组查询

SELECT   COUNT(*)   AS   人数,SGrade   AS    年级,SSex   AS   性别    FROM    Students

GROUP    BY    SGrade,SSex

ORDER    BY    SGrade

使用GROUP   BY关键字时,在SELECT列表中可以指定的列是有限制的,仅允许以下几项。

1、被分组的列

2、为每个分组返回一个值的表达式,如聚合函数计算出的列。

 

使用HAVING子句进行分组筛选

(1)查询总人数超过15的年级

SELECT   COUNT(*)   AS   人数,SGrade   AS    年级   FROM    Students

GROUP   BY   SGrade

但是还有一个条件:人数超过15的年级。这个时候,牵扯到分组统计后的条件限制,限制条件为COUNT(*)>15。这时候使用WHERE子句是不能满足查询要求的,因为WHERE子句只能对没有分组统计前的数据进行筛选。对分组后的条件的筛选必须使用HAVING子句,简单地说,HAVING子句用来对分组后的数据进行筛选,将“组”看做“列”来限定条件。

SELECT   COUNT(*)   AS   人数,SGrade   AS    年级   FROM    Students

GROUP   BY   SGrade

HAVING   COUNT(*)>15

 

(2)查询平均分达到及格的课程信息

SELECT   CourseID   AS   课程编号,AVG(Score)   AS   课程平均成绩

FROM  Score

GROUP   BY   CourseID

HAVING   AVG(Score)>=60

HAVING和WHERE子句可以在同一个SELECT语句中一起使用,使用顺序为

WHERE→GROUP   BY→HAVING

提示:在SELECT语句中,WHERE、GROUP   BY、HAVING子句和聚合函数的执行次序如下:WHERE子句从数据源中去掉不符合搜索条件的数据;GROUP   BY子句收集数据行到各个组中,统计函数为各个组计算统计值;HAVING子句去掉不符合其组搜索条件的各组数据行。

 

(3)查询每门课程及格总人数和及格学生的平均分

SELECT   COUNT(*)   AS   人数,AVG(Score)    AS   平均分,CourseID   AS   课程   FROM   Score

WHERE   Score>=60

GROUP   BY   CourseID

 

(4)查询每门课程及格总人数和及格平均分在80分以上的记录

SELECT   COUNT(*)    AS   人数,AVG(Score)   AS   平均分,CourseID    AS   课程   FROM   Score

WHERE    Score>=60

GROUP   BY   CourseID

HAVING   AVG(Score)>=80

 

(5)在按照部门分类的员工表中,查询“有两个及其以上员工的工资不低于2000的部门编号”

SELECT   部门编号,COUNT(*)    FROM   员工信息表

WHERE   工资>=2000

GROUP   BY   部门编号

HAVING   COUNT(*)>1

 

多表连接查询的分类

多表连接查询实际上是通过各个表之间共同列的关联性来查询数据的,它是关系数据库查询最主要的特征。

1、内连接查询

内连接查询是最典型、最常用的连接查询,他根据表中共同的列来进行匹配。特别是两个表存在主外键关系时通常会使用内连接查询。

A、在WHERE子句中指定连接条件

例如,查询学生姓名和成绩的T-SQL如下。

SELECT   Students.SName,Score.CourseID,Score.Score

FROM   Students,Score

WHERE   Students.SCode=Score.StudentID

上面这种形式的查询,相当于FROM后面紧跟了两个表名,然后在字段列表中用“表名.列名”来区分列,再在WHERE条件子句中加以判断,要求学生编号信息相等。

B、在FROM子句中使用INNER   JOIN…ON

上面的查询也可以通过以下的JOIN…ON子句来实现。

SELECT   S.SName,C.CourseID,C.Score

FROM   Students   AS   S

INNER   JOIN   Score   AS   C   ON   (S.SCode = C.StudentID)

在上面的内连接查询中:

  • INNER   JOIN用来连接两个表
  • INNER可以省略
  • ON用来设置条件
  • AS指定表的“别名”。如果查询的列名在用到的两个或多个表中不重复,则对这一列的引用不必用表名来限定。

再看一下T-SQL语句

SELECT   S.SName,C.CourseID,C.Score

FROM   Students   AS   S

INNER   JOIN   Score   AS   C   ON   (S.SCode = C.StudentID)

WHERE   C.Score>=60   AND   C.CourseID=1

内连接查询通常不仅仅连接两个表,有时候还会涉及三个表或者更多表。例如,除了学生信息表、学生成绩表之外,还存在课程表。上面的查询不仅仅要显示学生姓名、分数,而且要通过课程编号来显示课程名称表中对应课程的名称,可以使用以下三表连接查询的T-SQL语句来实现。

SELECT   S.SName   AS   学生姓名,CS.CourseName   AS   课程名称,C.Score   AS   考试成绩

FROM   Students   AS  S

INNER   JOIN   Score   AS   C   ON  (S.SCode=C.StudentID)

INNER   JOIN   Course   AS   CS   ON   (CS.CourseID=C.CourseID)

内连接查询的结果是从两个或两个以上表的组合中挑选出符合连接条件的数据,如果数据无法满足连接条件则将其忽略。在内连接查询中,参与连接的表的地位是平等的。

与内连接查询相对的方式称为外连接查询。在外连接查询中参与连接的表有主从之分,以主表的每行数据匹配从表的数据列,将符合连接条件的数据直接返回到结果集中;对那些不符合连接条件的列,讲填上NULL值(空值)后再返回到结果集中。

 

2、外连接查询

外连接查询时至少返回一个表中的所有记录,根据匹配条件有选择性的返回另一张表的记录。外链接可以是左外连接、右外连接。

A、左外连接查询

左外连接查询的结果集包括LEFT   JOIN子句中指定的左表的所有行,而不仅仅是连接列所匹配的行。若左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列均为空值。

左外连接查询使用LEFT   JOIN…ON或LEFT   OUTER   JOIN…ON关键字来进行表之间的关联。例如,要统计所有学生的考试情况,要求显示所有参加考试学生的每次考试分数,没有参将考试的学生也要显示出来。这时候,以学生信息表为主表(有时也叫左表)、学生成绩表为从表的左外连接查询如下T-SQL语句所示。

SELECT   S.SName,C.CourseID,C.Score

From   Students   AS   S

LEFT   OUTER   JOIN   Score   AS   C   ON   S.SCode=C.StudentID

其中,学生信息表中把每一条记录跟成绩表的记录进行数据匹配(匹配条件为S.SCode=C.StudentID)。若匹配成功,则返回到记录集(取S.Sname,C.CourseID,C.Score的值);若没有找到匹配的记录,则返回NULL值填充记录集。

有部分学生没有参加过任何科目考试,所以成绩表中没有相关的考试记录,对应的科目编号和成绩以NULL(空值)填充。

B、右外连接查询

右外连接查询与左外连接查询类似,只不过要包含右表中所有匹配的行。若右表中有的项在左表中没有对应的项,则以NULL值填充。

右外连接查询使用RIGHT   JOIN…ON或RIGHT   OUTER   JOIN…ON关键字来进行表之间的关联。例如在某数据库中,存在书籍表Titles和出版商表Publishers之间的右外连接将包括所有出版商,在Titles表中没有书名的出版商(很久没有出书了)也会被列出。

SELECT   Titles.Title_id,Titles.Title,Publishers.Pub_name

FROM   titles

RIGHT   OUTER    JOIN   Publishers   ON   Titles.Pub_id = Publishers.Pub_id

以上是关于S1/C#语言和数据库技术基础/11-连接查询和分组查询的主要内容,如果未能解决你的问题,请参考以下文章

S1/C#语言和数据库技术基础/10-模糊查询和聚合函数

S1/C#语言和数据库技术基础/08-用SQL语句操作数据

S1/C#语言和数据库技术基础/02-C#语法快速热身

S1/C#语言和数据库技术基础/01-第一个C#程序

S1/C#语言和数据库技术基础/03-使用属性升级MyBank

S1/C#语言和数据库技术基础/06-程序数据集散地:数据库