主要内容
1.使用SELECT语句进行单表查询、多表查询、连接查询、集合查询
2.使用聚合函数查询
3.使用GROUP BY子句对查询结果进行分组
4.使用HAVING子句对查询结果的分组进行筛选
5. 使用ORDER BY子句对查询结果按照一个或多个属性列的值的升序或降序实现排序
(1)使用SELECT语句进行单表查询、多表查询、连接查询、集合查询:
Step 1 打开SMSS,使用前面创建好的数据库S_C_SC;
Step 2 进行单表查询;
--查询全体学生的学号与姓名。
SELECT Sno,Sname FROM Student;
--查询经过计算的值(学生出生年份)
SELECT Sname,2022-Sage FROM Student;
发现无列名,修改T-SQL语句,赋列名为“birth”:
--查询经过计算的值(学生出生年份)
SELECT Sname,2022-Sage as 'birth' FROM Student;
Where子句下的单表查询:
--使用where子句对单表进行条件查询
--查询不是计科系、信息系的学生的姓名、学号和性别。
SELECT Sname, Sno, Ssex FROM Student WHERE Sdept NOT IN ('IS','CS');
Step 3 进行多表查询;
--多表查询
SELECT Student.Sname, Student.Sno, Course.Cname, SC.Grade
FROM Student, Course, SC
发现,Student表、Course表与SC表之间涉及到的所有数据均相连,导致数据无效,深究发现这是产生了笛卡尔积。
Step 4 进行连接查询;
连接查询分为等值连接、非等值连接和自身连接;
下面进行等值连接查询:
--等值连接查询
SELECT Student.*, Course.*, SC.*
FROM Student, Course, SC
WHERE Student.Sno = SC.Sno
AND Course.Cno = SC.Cno
将上述等值连接查询中的重复列去除,便是自然连接;
--自然连接
SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Grade, Course.Cno,Cname,Cpno,Ccredit, SC.Grade
FROM Student, Course, SC
WHERE Student.Sno = SC.Sno
AND Course.Cno = SC.Cno
从这里可以发现,在Step 3中多表查询时,Student表、Course表与SC表之间的所有数据均相连,导致数据无效,但是在此处的等值查询中引入了连接条件,便没有出现所有数据相连的情况;由此可见,笛卡尔积的产生条件是省略了连接条件或连接条件无效,这同样也告诉我们,在多表查询时,表间有相同的字段,才好进行有效的多表查询。
使用非等值连接查询选修信息系统课程并成绩高于85分的学生信息:
--非等值连接查询
--查询选修信息系统课程并成绩高于85分的学生信息
SELECT Student.Sno, Sname
FROM Student, SC
WHERE Student.Sno = SC.Sno
AND SC.Cno = 3
AND SC.Grade > 85;
在本次查询中,主要引入了成绩大于85这一条非等值的查询条件,构建了一个非等值查询。
使用自身连接查询间接先修课:
--自身连接
--查询间接先修课
SELECT FIRST.Cno, SECOND.Cpno, THIRD.Cname, FOURTH.Cname
FROM Course FIRST, Course SECOND, Course THIRD, Course FOURTH
WHERE FIRST.Cpno = SECOND.Cno
AND FIRST.Cno = THIRD.Cno
AND SECOND.Cpno = FOURTH.Cno
Step 4 进行集合查询;
集合查询分为并查询与交查询,其中并操作UNION是将多个查询结果合并起来时,并且系统自动去掉重复元组(UNION ALL:不去除重复元组),其中交操作INTERSECT指“既......又......”(连接的查询是不同属性时可转换为AND连接);
需要注意的是,参加集合操作的各查询结果的列数必须相同,对应项的数据类型也必须相同。
并查询:
--集合查询-并查询
--查询选修了课程1或者选修了课程2的学生
SELECT SC.Sno, Student.Sname
FROM SC, Student
WHERE Cno = 1
AND SC.Sno = Student.Sno
UNION
SELECT SC.Sno, Student.Sname
FROM SC, Student
WHERE Cno = 2
AND SC.Sno = Student.Sno;
交查询:
---交查询
--查询既是数学系的学生年龄又不大于19岁的学生
SELECT * FROM Student
WHERE Sdept='MA'
INTERSECT
SELECT * FROM Student
WHERE Sage <= 19;
(2)使用聚合函数查询
--聚合函数
--查询每个专业最大的年龄
SELECT Sdept, MAX(Sage)oldest_age
FROM Student
GROUP BY Student.Sdept
ORDER BY oldest_age;
--计算各个课程成绩的平均分
SELECT Cno, AVG(Grade)AVG_G
FROM SC
GROUP BY SC.Cno
ORDER BY AVG_G DESC;
在上述操作中,我使用聚合函数中的MAX与AVG函数分别查询了每个专业最大的年龄和各个课程成绩的平均分;
并使用GROUP BY子句对查询结果进行分组,其中查询年龄一例中是采取基于专业名(CS、IS、MA)进行分组,而查询平均分一例中是采取基于课程序号进行分组;
此外,我还使用了ORDER BY子句分别对上述两例按照年龄升序和平均分降序进行排列。
(3)进一步使用GROUP BY、HAVING以及ORDER BY子句对查询结果进行整理
--聚合函数进阶
--查询各专业平均已成年的班级内年龄最小的女生年龄
SELECT Sdept as Sdept_girl, MIN(Sage)youngest_age
FROM Student
WHERE Ssex = '女'
GROUP BY Sdept
HAVING AVG(Sage) >= 18
ORDER BY youngest_age
上述操作中,我使用聚合函数中的MIN函数,以及WHERE子句、GROUP BY子句、HAVING子句以及ORSER BY子句,实现了查询各专业平均已成年(年龄大于18岁)的班级内年龄最小的女生的具体年龄。
其中,WHERE子句实现了筛选出女生行,GROUP BY实现了基于专业进行分组,HAVING子句实现了在分组内筛选出平均年龄大于18岁的组(专业),最后的ORDER BY子句实现了基于最小年龄的升序排列。
总结
本文主要对基于SQL数据库的查询与数据整理汇总等操作进行初学演示,展示了单表查询、多表查询、连接查询和聚合查询多种查询方式,并且使用聚合函数计算、统计、汇总、检索结果,熟悉了多种查询条件的设置。
需要注意的是——使用GROUP BY子句进行查询结果的分组,使用ORDER BY子句以及其ASC关键字或DESC关键字对查询的数据进行升序或降序排列,使用WHERE子句对待查询数据进行筛选,使用HAVING子句对查询所得的分组进行筛选。