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-连接查询和分组查询的主要内容,如果未能解决你的问题,请参考以下文章