atwood-pan

 

SQL联结

1联结

🤔 那我们又该如何创建联结呢?

So easy!

👉 规定要联结的所有表以及它们如何关联就可以了。

在设置关联条件时,为避免不同表被引用的列名相同,我们需要使用完全限定列名(用一个点分隔表名和列名),否则会返回错误。

用法如下:
table1.common_field = table2.common_field
教师表的主键 id 为设置的关联条件为:
teachers.id = courses.teacher_id

1.1JOIN连接子句

SQL JOIN 连接子句用于将数据库中两个或者两个以上表中的记录组合起来。

其类型主要分为 INNER JOIN(内连接)、OUTER JOIN(外连接)、全连接(FULL JOIN)和交叉连接(CROSS JOIN),其中 OUTER JOIN 又可以细分为 LEFT JOIN(左连接)和 RIGHT JOIN(右连接)。

因此,我们主要使用的 JOIN 连接类型如下:

  • INNER JOIN:如果表中有至少一个匹配,则返回行
  • LEFT JOIN:即使右表中没有匹配,也从左表返回所有的行
  • RIGHT JOIN:即使左表中没有匹配,也从右表返回所有的行
  • FULL JOIN:只要其中一个表中存在匹配,则返回行
  • CROSS JOIN:又称笛卡尔积,两个表数据一一对应,返回结果的行数等于两个表行数的乘积

2内连接INNER JOIN

最常用也最重要的多表联结类型就是 INNER JOIN(内连接),有时候也被称作 EQUIJOIN(等值连接)。

内连接根据联结条件来组合两个表中的字段,以创建一个新的结果表。

假如我们想将表 1 和表 2 进行内连接,SQL 查询会逐个比较表 1 和表 2 中的每一条记录,来寻找满足联结条件的所有记录对。当联结条件得以满足时,所有满足条件的记录对的字段将会结合在一起构成结果表。

简单的说,内连接就是取两个表的交集,返回的结果就是连接的两张表中都满足条件的部分。

image

2.1内连接基本语法

基本语法有如下两种写法:

SELECT `table1`.`column1`, `table2`.`column2`...
FROM `table1`
INNER JOIN `table2`
ON `table1`.`common_field` = `table2`.`common_field`;

SELECT `table1`.`column1`, `table2`.`column2`...
FROM `table1`
JOIN `table2`
ON `table1`.`common_field` = `table2`.`common_field`;

注:INNER JOIN 中 INNER 可以省略不写

详细语法如下所示:

FROM table1
INNER JOIN table2
ON table1.common_field = table2.common_field

table1 和 table2 是内连接的两个表名,table1.common_field 和 table2.common_field
需要注意的是,联结条件需使用特定的 ON 子句给出。
表定义 1 :courses (课程表)

列名 类型 注释
id int unsigned 主键
name varchar 课程名称
student_count int 学生总数
created_at date 创建课程时间
teacher_id int 讲师 id

image

表定义 2 : teachers (教师表)

列名 类型 注释
id int 主键
name varchar 讲师姓名
email varchar 讲师邮箱
age int 讲师年龄
country varchar 讲师国籍

image

假如现在正处于新学期选课的阶段,我们想要查询一下新学期有哪些开设的课程可以选择,还想要获得开设这些课程教师的邮箱以便联系,我们该编写怎么样的 SQL 语句呢?

我们可以使用下面的 SQL 语句:

SELECT `c`.`id`, `c`.`name` AS `course_name`, `t`.`email` AS `teacher_email`
FROM `courses` `c`
    INNER JOIN `teachers` `t` ON `c`.`teacher_id` = `t`.`id`;

3外连接OUTER JOIN

外连接在生活中是经常用到的,外连接也是针对于两张表格之间,比如我们实际应用过程会发现,会有一些新任职的教师,还在实习期,并无对应课程安排,那若是按照上一节使用内连接的话,这些教师的课程信息将无法导出来,我们应该如何操作呢?

这个就要用到我们的外连接,外连接可以将某个表格中,在另外一张表格中无对应关系,但是也能将数据匹配出来。

在MySQL中,外连接查询会返回所操作的表中至少一个表的所有数据记录。在MySQL中,数据查询通过SQL语句 “OUTER JOIN…ON” 来实现,外连接查询可以分为以下三类:

  • 左外连接
  • 右外连接
  • 全外连接

外连接数据查询语法如下:

SELECT column_name 1,column_name 2 ... column_name n
    FROM table1
        LEFT | RIGHT | FULL  (OUTER) JOIN table2
        ON CONDITION;

3.1左外连接LEFT JOIN

外连接查询中的左外连接就是指新关系中执行匹配条件时,以关键字 LEFT JOIN 左边的表为参考表。

左外连接的结果包括 LEFT OUTER 子句中指定的左表的所有行,而不仅仅是连接列所匹配的行,这就意味着,左连接会返回左表中的所有记录,加上右表中匹配到的记录。如果左表的某行在右表中没有匹配行,那么在相关联的结果行中,右表的所有选择列表均为空值。

语法:

SELECT column_name 1,column_name 2 ... column_name n
    FROM table1
        LEFT JOIN table2
        ON CONDITION ;

现在学校想要统计所有的在校教师姓名及其所教课程的名称,希望能得到你的帮助。

在这里我们要查询的信息是在俩个表当中的,我们要先把表关联到一起(“teachers” 作为左表,“courses“ 作为右表)然后在进行查找。

使用 SQL 中子查询的方式如下:

SELECT c.name AS course_name, t.name AS teacher_name
FROM teachers t
    LEFT JOIN courses c ON c.teacher_id = t.id;

3.2右外连接RIGHT JOIN

外连接查询中的右外连接是指新关系中执行匹配条件时,以关键字 RIGHT JOIN 右边的表为参考表,如果右表的某行在左表中没有匹配行,左表就返回空值。

SELECT column_name 1,column_name 2 ... column_name n
    FROM table1
        RIGHT JOIN table2
        ON CONDITION ;

👇 我们可以通过下面的实例来感受一下 RIGHT JOIN 的用法。

现在学校想要统计所有的在校教师姓名、教师邮箱及其所教课程的名称,希望能得到你的帮助。

在这里我们将 “teachers” 作为右表,“courses“ 作为左表然后在进行查找。

使用 SQL 中子查询的方式如下:

SELECT c.name AS course_name, t.name AS teacher_name,t.email AS teacher_email
FROM courses c
    RIGHT JOIN teachers t ON c.teacher_id = t.id;

3.3全外连接FULL(OUTER) JOIN

FULL OUTER JOIN 关键字只要左表(table1)和右表(table2)其中一个表中存在匹配,则返回行

FULL OUTER JOIN 关键字结合了 LEFT JOIN 和 RIGHT JOIN 的结果。

注:MySQL 数据库不支持全连接,想要实现全连接可以使用 UNION ALL 来将左连接和右连接结果组合在一起实现全连接。
UNION :联合的意思,即把两次或多次查询结果合并起来

要求:两次查询的列数必须一致,同时,每条 SELECT 语句中的列的顺序必须相同

推荐:列的类型可以不一样,但推荐查询的每一列,相对于的类型应该一样

可以来自多张表的数据:多次sql语句取出的列名可以不一致,此时以第一个sql语句的列名为准,即UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
如果不同的语句中取出的行,有完全相同(这里表示的是每个列的值都相同),那么 UNION 会将相同的行合并,最终只保留一行。也可以这样理解,UNION 会去掉重复的行。
如果不想去掉重复的行,可以使用 UNION ALL 。
如果子句中有 order by,limit,需用括号()包起来。推荐放到所有子句之后,即对最终合并的结果来排序或筛选。

先左连接,后右连接

SELECT column_name 1,column_name 2 ... column_name n
    FROM table1
        LEFT JOIN table2 ON CONDITION 
UNION
SELECT column_name 1,column_name 2 ... column_name n
    FROM table1
        RIGHT JOIN table2 ON CONDITION ;

eg:

SELECT `c`.`name` AS `course_name`, `t`.`age` AS `teacher_age`
FROM `courses` `c`
	LEFT JOIN `teachers` `t` ON `c`.`teacher_id` = `t`.`id`
UNION
SELECT `c`.`name` AS `course_name`, `t`.`age` AS `teacher_age`
FROM `courses` `c`
	RIGHT JOIN `teachers` `t` ON `c`.`teacher_id` = `t`.`id`;

posted on 2023-03-12 15:59  JavaCoderPan  阅读(44)  评论(0编辑  收藏  举报

导航