一、连接查询
连接查询是SQL语言最强大的功能之一,它可以执行查询时动态的将表连接起来,然后从中查询数据。
1.1、连接两表的方法
在SQL中连接两表可以有两种方法,一种是无连接规则连接,另一种是有连接规则连接。
- 无连接规则连接
无连接规则连接后得到的结果是两个表中的每一行都互相连接,即结果为笛卡尔积(笛卡尔积(Cartesian Product)是数据库和集合论中的一个概念。它是指将两个集合中的每一个元素进行配对,形成一个新的集合。在数据库的上下文中,笛卡尔积是指在 SQL 查询中将两个表的所有可能的行组合在一起,生成所有可能的行对组合)。
SELECT *(或字段列表) FROM 表名1,表名2; |
FROM子句中的表名1和表名2是要连接的两个表的名称,用逗号(,)将其隔开;如果SELECT子句中使用星号(*),则查询结果中显示两个表的所有字段。
SELECT * FROM t1,t2; |
运行结果显示了t1表的所有记录与t2表的所有记录进行了连接,即得到了笛卡尔积;但实际上,这并不是用户想要的结果,因为用户需要需要的是正确的连接,而并不是每行都连接起来,所以应该给连接设定连接规则。
多表无连接规则连接和两表无连接规则连接基本相同,只是在FROM子句中需要列出更多的表名,表名之间用逗号隔开,连接得到的结果同样也是笛卡尔积。
- 有连接规则连接
有连接规则连接其实就是在无连接规则的基础上,加上WHERE子句指定连接规则的连接方法。
SELECT *(或字段列表) FROM 表名1,表名2 WHERE 连接规则; |
- 示例:
SELECT * FROM t1,t2 WHERE t1.职工号=t2.职工号; |
其中,连接规则是:t1.职工号=t2.职工号
这种使用等于号组成的连接,实际上叫等值连接;只有两表有共同的字段时才可以使用等值连接,例如,t1和t2表有共同的字段—职工号,只有这样才可以使用等值连接的方法连接两表。
在上面的连接规则表达式中,字段名前加上了数据表的名称,并用英文中的句号(.)将其隔开,这是因为两个表中有相同的字段名,如果不加以修饰说明,DBMS将无法辩认是哪个表的字段;所以在多表连接时,如果使用表中相同名称的字段,则应当在其前面加上表名。
Tips:在多表连接时,即使不要求在表独有的字段前加表名,但建议还是加上表名;因为这样会很清楚地表示哪个字段属于哪个表,这将对以后的维护起到很好的作用。
1.2、使用笛卡尔积解决录入难题
- 示例:使用stu_info表和stu_course表的笛卡尔积,生成一个必修课成绩表(bxk_score)的内容,要求是每个学生都应该选择所有的必修课。
- 如果SQL运行环境为MySQL或Oracle,则其查询语句如下
CREATE TABLE bxk_score AS SELECT stu_info.id as 学号,stu_info.name AS 姓名,stu_course.ID AS 课号,stu_course.course AS 课名 FROM stu_info,stu_course WHERE stu_course.type='必修' ORDER BY 学号,课号; |
CREATE TABLE bxk_score AS这里的 AS 关键字表示“使用以下 SELECT 语句的结果作为新表的数据来源”。
- 如果SQL 运行环境为SQL Server,则其查询语句如下:
SELECT stu_info.id as 学号,stu_info.name AS 姓名,stu_course.ID AS 课号,stu_course.course AS 课名 INTO bxk_score FROM stu_info,stu_course WHERE stu_course.type='必修' ORDER BY stu_info.id,stu_course.ID; |
SELECT s.id AS 学号, s.name AS 姓名, c.ID AS 课号, c.course AS 课名 INTO bxk_score FROM stu_info s, stu_course c WHERE c.type = '必修' ORDER BY s.id, c.ID; |
- 执行顺序
- FROM:首先执行 FROM 子句。这里使用了表别名 s 和 c,表示 stu_info 表和 stu_course 表。
- WHERE:根据 WHERE 子句中的条件筛选出满足条件的行,即 stu_course 表中 type 列值为 '必修' 的行。
- SELECT:选择 stu_info 表中的 id 列并命名为 学号,选择 stu_info 表中的 name 列并命名为 姓名,选择 stu_course 表中的 ID 列并命名为 课号,选择 stu_course 表中的 course 列并命名为 课名。
- ORDER BY:对结果集按照 学号 和 课号 进行排序。
- INTO(CREATE TABLE AS SELECT):最后,将查询结果存储到名为 bxk_score 的新表中。
本例使用了多数人觉得没用的求笛卡尔积的方法很好地解决了一个录入上的难题。
1.3、使用两表连接查询数据
数据库操作中,比起使用笛卡尔积,使用有连接规则的连接查询会更频繁一些。
示例:查询名叫“张三”的学生的所有课程的平时成绩和考试成绩
分析:stu_info表中有学生姓名,但没有成绩,而存储成绩的score表中有成绩,但没有姓名,不过两个表都有一个共享字段—学号,所以可以将这两个表连接起来进行查询:
SELECT s.id as 学号,s.name AS 姓名,c.c_id AS 课号,c.result2 AS 平时成绩,c.result1 AS 考试成绩 FROM stu_info s,score c WHERE s.name='张三' AND s.id=c.s_id ORDER BY c.result1 DESC,c.result2 DESC; |
其中WHERE子句中的条件表达式使用逻辑运算符AND,将查询条件(s.name=’张三’)和连接规则(s.id=c.s_id)整合为一体。
未完待续。。。