数据库是存储数据集合的容器,一般数据库中都存在多个表,这一篇文章主要处理多个表的查询,一个表中的数据是同一种类型的数据集合,数据库中的每个表都有唯一名字来标识。描述表的元信息就是所谓的模式schema,模式用来描述数据库中特定的表,包括表的字段名,数据类型,约束关系等。
关键词 Join Union
一、多表查询
从多个表查询数据,一次查询多个表的数据,查询的结果也是一个二维表,这种多表查询又称笛卡尔查询,假如两个表查询,表一有M行记录,表二有N行记录,则多表查询返回记录数为M*N行。SELECT * FROM <表1> <表2>
SELECT * FROM student,course; student表8行数据,course表6行数据,返回48条数据。
由于返回的列名有相同的,我们可以使用以下别名策略:
SELECT s.no sno, s.name sname, s.age,s.sex,s.department,c.no cno,c.name coursename, c.hours hours FROM student s,course c;
二、union查询
利用 UNION可对多条SELECT 语句,将它们的结果组合成一个结果集。UNION 必须由两条或两条以上的 SELECT 语句组成; UNION每个查询必须包含相同的列、表达式或聚集函数; 列数据类型必须兼容,类型不必完全相同,但必须是数据库可以自动转换的类型; UNION会从查询结果集中自动去除重复的行。如果想返回所有的匹配行,可使用 UNION ALL 而不是 UNION。
SELECT * FROM student WHERE sex='男'; 返回所有男性学生,共返回5条。
SELECT * FROM student WHERE age > 20;返回所有年龄大于20的学生,共返回2条;
SELECT * FROM student WHERE sex='男' UNION SELECT * FROM student WHERE age > 20;返回两个条件的union,去重后共返回6条。
三、关系模型和主键、外键
关系数据库是创建在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据,现实世界中的各种实体以及实体之间的各种联系均用关系模型来表示。关系模型本质上就是若干个二维表,类似Excel的多个sheet。
主键是指能够唯一标识表中每一行的一列或者一组列,主键不允许为NULL。对于关系表,有个很重要的约束,就是任意两条记录不能重复,最好不使用任何业务相关的字段作为主键。关系数据库实际上还允许通过多个字段唯一标识记录,即两个或更多的字段都设置为主键,这种主键被称为联合主键。主键的作用是保证唯一性。
外键:外键并不是通过列名实现的,而是通过定义外键约束实现的,可以把数据与另一张表关联起来,这种列称为外键。存在一对多,多对多,一对一的关系。表的外键是另一表的主键, 外键可以有重复的, 可以是空值。外键的作用是用于和其他表进行关联。
Student表中no是主键:
Course表中no是主键:
Coursegrade表中sno和cno都是外键,可以和student中的no以及course中的no进行关联。
四、关联查询
关联查询主要基于关系模型,依赖于主键和外键处理。SQL 最强大的功能之一就是能在数据查询的执行中关联查询join,Excel中我们都知道vlookup,创建关联查询需要指定要关联的所有表以及关联它们的方式。关联方式有内关联(inner join),左外连接( left outer join),右外连接(right outer join),全外连接(full outer join)。
获取所有选择C01数据库课程学生信息以及课程成绩,
SELECT s.*,c.cno,c.grade FROM student s INNER JOIN coursegrade c ON s.no = c.sno WHERE c.cno='c01';
内连接查询,SELECT s.*,c.cno,c.grade FROM student s INNER JOIN coursegrade c ON s.no = c.sno;
默认和SELECT s.*,c.cno,c.grade FROM student s, coursegrade c WHERE c.sno=s.no;查询效果一样,平时我们用的更多的是这个用法。
左外连接,SELECT s.*,c.cno,c.grade FROM student s LEFT OUTER JOIN coursegrade c ON s.no = c.sno;发现比内连接多了两条数据,cno为空的数据。
再看一个从三个表进行关联查询,获取所有所有学生选课的所有成绩:
SELECT s.*,c.*,sc.grade FROM student s,course c, coursegrade sc WHERE s.no=sc.sno AND c.no=sc.cno;