00104 SQL查询进阶2:多表联合查询JOIN

**

一、引言

**
关系型数据库的精髓就在于,它以不同的表作为数据单元储存不同的数据,同时又在不同表之间建立联系,把表内的数据链接起来。
数据库的这一特性,一方面缩减了单个表的规模,防止了大量的数据冗余,另一方面也导致我们无法通过查询一个表得到我们想要的所有数据。
举个例子,我们在一个student表中存储学生的姓名、学号、性别等基本信息,而在grades表中存储学生的语文和数学成绩,那怎么才能知道每一条成绩是哪个学生的呢?我们在grades表中也加入了一列,用来存储学生的学号。
所以,当我们想知道张三的语文成绩时,首先要从student表得到张三的学号001,然后在grades表中查找学号列为001的那一行,从而得到成绩。在这一过程中,我们所作的工作,就是把两个表通过它们之间的公用字段(字段就是列)连接了起来。
SQL语言提供了把几个表连起来的关键字,用于把不同表的数据连起来,得到我们想要的结果,这个关键字就是JOIN。

二、JOIN的基本语法

 SELECT table1.column1, table2.column2 
     FROM table1 XX join table2... 
     ON
     table1.column_name= table2.column_name

在上述语句中我们留出了XX,是因为JOIN有几种不同的形式,分别代表不同的结合方式:

为了方便理解,我们先给出一个概念,请把每个表想象成一个集合,JOIN操作就是在进行集合运算。

内部结合INNER JOIN

也就是取两个表的交集

SELECT table1.column1, table2.column2 
    FROM table1 INNER JOIN table2... 
    ON table1.column_name= table2.column_name

简化代码——给表起个别名:

SELECT 1.column1, 2.column2 
    FROM table1 1
         INNER JOIN table2 2
    WHERE 1.column_name= 2.column_name

内部结合又可以分为以下两种情况:

  • 等值结合:利用两个表通用字段的相等来实现结合
    • WHERE table1.column_name = table2.column_name
  • 不等值结合:利用两个表通用字段的不相等来实现结合
    • WHERE table1.column_name != table2.column_name
    • 不等值结合常常会找出很多没用的数据,它可以和等值结合连起来用来验错,比如说身份证号相等但是姓名不等的,那就是错误数据,以此为条件查询看有没有结果,有就是有错

外部结合OUTER JOIN:

外部结合包括三种情况:

SELECT table1.column1, table2.column2 
    FROM table1 LEFT/RIGHT/FULL [OUTER] JOIN table2 
    ON table1.column_name= table2.column_name

LEFT,RIGHT,FULL JOIN其实都是外部结合,因为outer是可以不写的,所以学习时常常会导致困扰,总的来讲只有内部结合和外部结合两大类,而外部结合又分为左连接LEFT、右连接RIGHT、全连接FULL三种

  • 左连接:显示左表全部数据,右表只显示符合where条件的 ——左表+交集

  • 右连接:显示右表全部数据,左表只显示符合where条件的 ——右表+交集

  • 全连接:where谁也不影响——并集

当然,外部结合也可以分等值和不等值,就看结合条件怎么写了。

总结成如下口诀

(某大神博客里写的,并非原创)
左连接where只影向右表
右连接where只影响左表
全连接where谁也不影响
内连接where影响左右表

自结合:

通过给一个表赋两个别名,从而可以将它视作两个表来进行结合。
首先再重申一次,JOIN从整体来讲只有内连接和外连接两大类,自结合其实只是一种特殊情况,可以说,它是从另一个分类维度来看的,而不是和内连接、外连接并行的维度。所以,自结合可以是内部结合,也可以是外部结合。

SELECT 1.column1, 2.column1 
    FROM table1 1 INNER/LEFT/RIGHT/FULL JOIN table1 2 
    ON 1.column2=2.column1
 /1和2都是同一个表table1的别名

比如说一个企业职工信息表jobinfo,记录了职工姓名name、编号code、职位position、上级supercode,但是上级给出的是上级的编号而不是姓名。
当我们想要查询每个职工对应的上级姓名时,我们可以返回两列职工姓名,而让第二列职工姓名对应的编号,等于第一列职工姓名对应的上级编号,这样就得出了每个职工上级职工的姓名。
写成代码就是:

SELECT 1.code,1.name,1.supercode,2.name
    FROM jobinfo 1 
    LEFT JOIN jobinfo 2 
    ON  1.supercode=2.code
/注意这里我们用的是LEFT JOIN,从而返回1表中的所有行,不管该员工到底有没有对应的上级。
/如果变成INNER JOIN, CEO这种没有上级的员工(也就是supercode字段为空),就不会出现在返回结果中。

TIPS:

内部结合还有另一种常用语法:

 SELECT table1.column1, table2.column2 
     FROM table1, table2... 
     WHERE table1.column_name= table2.column_name

对于初学者来讲这种语法似乎更友好。但是我认为使用上面给出的语法能够帮助学习时更好的区分内部结合和外部结合的概念。

猜你喜欢

转载自blog.csdn.net/shengxiaobufu/article/details/73800925