数据查询
数据查询格式
SELECT [ALL | DISTINCT] <目标列表达式>
FROM <表名或视图名> [, <表名或视图名>] ... | (SELECT 语句)
[AS] <别名>
[WHERE <条件表达式>]
[GROUP BY <列名1> [HAVING <条件表达式>]
[ORDER BY <列名2> [ASC | DESC]];
连接查询
连接查询的格式
SELECT ... FROM tableA ??? JOIN tableB ON tableA.column1 = tableB.column2;
连接查询的主要目的是为了能够从多个表中获得我们想要的数据,例如下面这个问题
【表名和字段】
–1.学生表
student(sid,sname,gender,class_id) –学生编号,学生姓名,学生性别,班级编号
–2.课程表
course(cid,cname,tid) –课程编号, 课程名称, 教师编号
–3.教师表
teacher(tid,tname) –教师编号,教师姓名
–4.成绩表
score(sid,cid,number) –学生编号,课程编号,分数
注意sql语句中的表名要与此一致。
【要求】
查询李云同学选修的所有课程名称和成绩。
【输出格式】
课程名称,分数
因为课程名称和分数在两张不同的表中,所以我们需要将两张表进行连接,然后再从连接的表中得到我们想要的结果。
连接的类型分为内连接和外连接。
内连接是指只有在两个表上都存在的数据才会在结果中生成连接的结果,我们可以把它当做两个集合的交集。外连接分为左外连接和右外连接,左外连接是选出左表存在的记录,右外连接是选出右表存在的记录。
聚合函数与分组查询
聚合函数
统计元组个数:COUNT(*)
统计一列中值的个数:COUNT([DISTINCT | ALL] <列名>)
计算一列值的总和(此列必须为数值型): SUM([DISTINCT | ALL] <列名>)
计算平均值:AVG([DISTINCT | ALL] <列名>)
求一列中的最大值和最小值:MAX(), MIN()
GROUP BY 子句分组
细化聚集函数的作用对象,如果未对查询结果分组,聚合函数将作用于整个查询结果,对查询结果分组后,聚合函数将分别作用于每个组,按指定的一列或多列值分组,值相等的为一组。
注意
使用GROUP BY对数据进行分组后是不能够使用WHERE子句作为条件表达式,例如
查询平均成绩大于90分的学生学号和平均成绩
下面的语句是不对的:
SELECT Sno, AVG(Grade) FROM SC WHERE AVG(Grade) >= 90 GROUP BY Sno;
因为WHERE子句是不能用作聚合函数作为条件表达式的。
正确的查询语句应该是:
SELECT Sno, AVG(Grade) FROM SC GROUP BY Sno HAVING AVG(Grade) >= 90;
HAVING 短语与 WHERE 子句的区别:
作用对象不同
WHERE子句作用于基表或试图,从中选择满足条件的元组
HAVING短语作用于组,从中选择满足条件的组
练习
查询各科成绩最高分与最低分。并以如下形式显示:课程ID,最高分,最低分
SELECT cid, MAX(number), MIN(number) FROM score WHERE MAX(number) IS NOT NULL GROUP BY cid;
查询姓名完全相同的学生名单,并统计人数。输出格式为:姓名,人数。
SELECT sname, COUNT(*) FROM student GROUP BY sname HAVING COUNT(*) > 1;
(这次考试的时候出了一道类似的题目,但是当时自己对这块知识掌握的并不是太牢固当时没有写出来)
统计每门课程的学生选修人数(超过5人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列 。
SELECT c_id, COUNT(s_id) AS num FROM score GROUP BY c_id HAVING num > 5 ORDER BY num DESC, c_id ASC;