一般情况下一个网站的数据库通常会有多张数据表组成,这些数据表分别存储网站不同区域的内容。数据表之间可以用类似 ID 的字段来关联,在查询的时候可以通过一条语句来查询多张表的内容。例如 论坛的数据库,帖子和用户信息就是分开存储的,在查询的时候通过 ID 来关联就能查询出 帖子内容 和 对应的 用户信息。
MySQL 的多表查询有多种关联方式,这里主要写的是 内连接
和 外连接
。其它的以后再写。
演示表格
这里使用两张数据表来演示,表名分别为 user
和 message
。下面是两张表的内容:
user
:
+----+--------+------------------+------------+
| id | gender | email | name |
+----+--------+------------------+------------+
| 1 | 0 | 2585@qq.com | Jack |
| 2 | 0 | 232454@qq.com | Mark |
| 3 | 1 | 245522@qq.com | Alice |
| 4 | 1 | 121455@qq.com | Jerry |
| 5 | 0 | 588855@163.com | John |
| 6 | 0 | 785588@gmail.com | Kennedy |
| 7 | 0 | mysql@qq.com | Eisenhower |
| 8 | 1 | jjjiw@yahoo.com | Ruby |
+----+--------+------------------+------------+
message
:
+----+---------+-----------------+----------+
| id | user_id | content | time |
+----+---------+-----------------+----------+
| 2 | 1 | My Name is Jack | 1574586 |
| 3 | 2 | My Name is Mark | 548548 |
| 4 | 1 | Are you OK | 45888966 |
| 5 | 1 | Hello Thank you | 458856 |
| 6 | 2 | Awesome | 558856 |
+----+---------+-----------------+----------+
这是两张比较简单的数据表,这两张表之间唯一有关系的就是 user
表的 id
和 message
表的 user_id
。
内连接
内连接是 MySQL 中用的比较多的一种连接查询,内连接可以返回两张表中满足关联条件的行。下面查询 user
表 和 message
表,用 user
表的 id
来关联 message
表的 user_id
:
SELECT * FROM
user INNER JOIN message
ON
user.id = message.user_id
下面是查询结果:
+----+--------+---------------+------+----+---------+-----------------+----------+
| id | gender | email | name | id | user_id | content | time |
+----+--------+---------------+------+----+---------+-----------------+----------+
| 1 | 0 | 2585@qq.com | Jack | 2 | 1 | My Name is Jack | 1574586 |
| 2 | 0 | 232454@qq.com | Mark | 3 | 2 | My Name is Mark | 548548 |
| 1 | 0 | 2585@qq.com | Jack | 4 | 1 | Are you OK | 45888966 |
| 1 | 0 | 2585@qq.com | Jack | 5 | 1 | Hello Thank you | 458856 |
| 2 | 0 | 232454@qq.com | Mark | 6 | 2 | Awesome | 558856 |
+----+--------+---------------+------+----+---------+-----------------+----------+
user
表和 message
表都有一个 id
,前面的 id
是 user
表的,后面的 id
是 message
表的。
user
表虽然有很多行但这里只查询出两行,只有在 message
表中有 user_id
的 user
才会被查询出来。
其中的 user INNER JOIN message
就是让 user
表来连接 message
表。user.id = message.user_id
就是通过 user
表的 id
来关联 message
表的 user_id
。
下面查询 Mark
的用户信息和 Mark
的留言:
SELECT * FROM
user INNER JOIN message
ON
user.id = message.user_id
WHERE
name = 'Mark'
查询结果:
+----+--------+---------------+------+----+---------+-----------------+--------+
| id | gender | email | name | id | user_id | content | time |
+----+--------+---------------+------+----+---------+-----------------+--------+
| 2 | 0 | 232454@qq.com | Mark | 3 | 2 | My Name is Mark | 548548 |
| 2 | 0 | 232454@qq.com | Mark | 6 | 2 | Awesome | 558856 |
+----+--------+---------------+------+----+---------+-----------------+--------+
下面调转一下两张表的顺序:
SELECT * FROM
message INNER JOIN user
ON
message.user_id = user.id
下面是查询结果:
+----+---------+-----------------+----------+----+--------+---------------+------+
| id | user_id | content | time | id | gender | email | name |
+----+---------+-----------------+----------+----+--------+---------------+------+
| 2 | 1 | My Name is Jack | 1574586 | 1 | 0 | 2585@qq.com | Jack |
| 3 | 2 | My Name is Mark | 548548 | 2 | 0 | 232454@qq.com | Mark |
| 4 | 1 | Are you OK | 45888966 | 1 | 0 | 2585@qq.com | Jack |
| 5 | 1 | Hello Thank you | 458856 | 1 | 0 | 2585@qq.com | Jack |
| 6 | 2 | Awesome | 558856 | 2 | 0 | 232454@qq.com | Mark |
+----+---------+-----------------+----------+----+--------+---------------+------+
论坛或留言板只需要通过内连接就能同时输出留言和用户信息。
外连接
外连接又可以分为 左外连接
和 右外连接
。
左外连接
左外连接
就是返回左表中的全部内容和右表中符合关联条件的内容。
下面还是查询 user
表和 message
表:
SELECT * FROM
user LEFT JOIN message
ON
user.id = message.user_id
下面是查询结果:
+----+--------+------------------+------------+------+---------+-----------------+----------+
| id | gender | email | name | id | user_id | content | time |
+----+--------+------------------+------------+------+---------+-----------------+----------+
| 1 | 0 | 2585@qq.com | Jack | 2 | 1 | My Name is Jack | 1574586 |
| 2 | 0 | 232454@qq.com | Mark | 3 | 2 | My Name is Mark | 548548 |
| 1 | 0 | 2585@qq.com | Jack | 4 | 1 | Are you OK | 45888966 |
| 1 | 0 | 2585@qq.com | Jack | 5 | 1 | Hello Thank you | 458856 |
| 2 | 0 | 232454@qq.com | Mark | 6 | 2 | Awesome | 558856 |
| 3 | 1 | 245522@qq.com | Alice | NULL | NULL | NULL | NULL |
| 4 | 1 | 121455@qq.com | Jerry | NULL | NULL | NULL | NULL |
| 5 | 0 | 588855@163.com | John | NULL | NULL | NULL | NULL |
| 6 | 0 | 785588@gmail.com | Kennedy | NULL | NULL | NULL | NULL |
| 7 | 0 | mysql@qq.com | Eisenhower | NULL | NULL | NULL | NULL |
| 8 | 1 | jjjiw@yahoo.com | Ruby | NULL | NULL | NULL | NULL |
+----+--------+------------------+------------+------+---------+-----------------+----------+
查询出了所有 user
表的内容和一部分 message
表的内容,没有被 user
表的 id
关联到的 message
表就返回 NULL
。
下面查询 user
表中 name
为 Jerry
的留言:
SELECT * FROM
user LEFT JOIN message
ON
user.id = message.user_id
WHERE
name = 'Jerry'
查询结果:
+----+--------+---------------+-------+------+---------+---------+------+
| id | gender | email | name | id | user_id | content | time |
+----+--------+---------------+-------+------+---------+---------+------+
| 4 | 1 | 121455@qq.com | Jerry | NULL | NULL | NULL | NULL |
+----+--------+---------------+-------+------+---------+---------+------+
因为 左外连接
会返回左表中的所有内容,所以哪怕没有关联到右表也会返回内容。如果是 内连接
在没有关联到内容的情况下就不会返回数据。
右外连接
右外连接
和 左外连接
相反,右外连接
会返回左表中符合关联条件的内容和右表中的所有内容。
下面还是查询 user
表和 message
表:
SELECT * FROM
user RIGHT JOIN message
ON
user.id = message.user_id
下面是查询结果:
+------+--------+---------------+------+----+---------+-----------------+----------+
| id | gender | email | name | id | user_id | content | time |
+------+--------+---------------+------+----+---------+-----------------+----------+
| 1 | 0 | 2585@qq.com | Jack | 2 | 1 | My Name is Jack | 1574586 |
| 2 | 0 | 232454@qq.com | Mark | 3 | 2 | My Name is Mark | 548548 |
| 1 | 0 | 2585@qq.com | Jack | 4 | 1 | Are you OK | 45888966 |
| 1 | 0 | 2585@qq.com | Jack | 5 | 1 | Hello Thank you | 458856 |
| 2 | 0 | 232454@qq.com | Mark | 6 | 2 | Awesome | 558856 |
+------+--------+---------------+------+----+---------+-----------------+----------+
返回了右表中所有的内容和左表中符合关联条件的内容。因为右表的内容比左表的少,所以左表没有返回 NULL
。
以上就是 MySQL 的三种连接查询方式,一般在实际开发中 内连接
会用的多一些。