首页 数据库 mysql教程 几种MySQL中的联接查询操作方法总结_MySQL

几种MySQL中的联接查询操作方法总结_MySQL

Jun 01, 2016 pm 01:00 PM
mysql

前言

现在系统的各种业务是如此的复杂,数据都存在数据库中的各种表中,这个主键啊,那个外键啊,而表与表之间就依靠着这些主键和外键联系在一起。而我们进行业务操作时,就需要在多个表之间,使用sql语句建立起关系,然后再进行各种sql操作。那么在使用sql写出各种操作时,如何使用sql语句,将多个表关联在一起,进行业务操作呢?而这篇文章,就对这个知识点进行总结。

联接查询是一种常见的数据库操作,即在两张表(多张表)中进行匹配的操作。MySQL数据库支持如下的联接查询:

  •     CROSS JOIN(交叉联接)
  •     INNER JOIN(内联接)
  •     OUTER JOIN(外联接)
  •     其它

在进行各种联接操作时,一定要回忆一下在《SQL逻辑查询语句执行顺序》这篇文章中总结的SQL逻辑查询语句执行的前三步:

  •     执行FROM语句(笛卡尔积)
  •     执行ON过滤
  •     添加外部行

每个联接都只发生在两个表之间,即使FROM子句中包含多个表也是如此。每次联接操作也只进行逻辑查询语句的前三步,每次产生一个虚拟表,这个虚拟表再依次与FROM子句的下一个表进行联接,重复上述步骤,直到FROM子句中的表都被处理完为止。
前期准备

 1.新建一个测试数据库TestDB;

      

create database TestDB;
登录后复制

创建测试表table1和table2;

   CREATE TABLE table1
   (
     customer_id VARCHAR(10) NOT NULL,
     city VARCHAR(10) NOT NULL,
     PRIMARY KEY(customer_id)
   )ENGINE=INNODB DEFAULT CHARSET=UTF8;

   CREATE TABLE table2
   (
     order_id INT NOT NULL auto_increment,
     customer_id VARCHAR(10),
     PRIMARY KEY(order_id)
   )ENGINE=INNODB DEFAULT CHARSET=UTF8;

登录后复制

插入测试数据;

   INSERT INTO table1(customer_id,city) VALUES('163','hangzhou');
   INSERT INTO table1(customer_id,city) VALUES('9you','shanghai');
   INSERT INTO table1(customer_id,city) VALUES('tx','hangzhou');
   INSERT INTO table1(customer_id,city) VALUES('baidu','hangzhou');

   INSERT INTO table2(customer_id) VALUES('163');
   INSERT INTO table2(customer_id) VALUES('163');
   INSERT INTO table2(customer_id) VALUES('9you');
   INSERT INTO table2(customer_id) VALUES('9you');
   INSERT INTO table2(customer_id) VALUES('9you');
   INSERT INTO table2(customer_id) VALUES('tx');

登录后复制

准备工作做完以后,table1和table2看起来应该像下面这样:

   mysql> select * from table1;
   +-------------+----------+
   | customer_id | city   |
   +-------------+----------+
   | 163     | hangzhou |
   | 9you    | shanghai |
   | baidu    | hangzhou |
   | tx     | hangzhou |
   +-------------+----------+
   4 rows in set (0.00 sec)

   mysql> select * from table2;
   +----------+-------------+
   | order_id | customer_id |
   +----------+-------------+
   |    1 | 163     |
   |    2 | 163     |
   |    3 | 9you    |
   |    4 | 9you    |
   |    5 | 9you    |
   |    6 | tx     |
   +----------+-------------+
   7 rows in set (0.00 sec)

登录后复制

准备工作做的差不多了,开始今天的总结吧。
CROSS JOIN联接(交叉联接)

CROSS JOIN对两个表执行FROM语句(笛卡尔积)操作,返回两个表中所有列的组合。如果左表有m行数据,右表有n行数据,则执行CROSS JOIN将返回m*n行数据。CROSS JOIN只执行SQL逻辑查询语句执行的前三步中的第一步。

CROSS JOIN可以干什么?由于CROSS JOIN只执行笛卡尔积操作,并不会进行过滤,所以,我们在实际中,可以使用CROSS JOIN生成大量的测试数据。

对上述测试数据,使用以下查询:

select * from table1 cross join table2;

登录后复制

就会得到以下结果:

+-------------+----------+----------+-------------+
| customer_id | city   | order_id | customer_id |
+-------------+----------+----------+-------------+
| 163     | hangzhou |    1 | 163     |
| 9you    | shanghai |    1 | 163     |
| baidu    | hangzhou |    1 | 163     |
| tx     | hangzhou |    1 | 163     |
| 163     | hangzhou |    2 | 163     |
| 9you    | shanghai |    2 | 163     |
| baidu    | hangzhou |    2 | 163     |
| tx     | hangzhou |    2 | 163     |
| 163     | hangzhou |    3 | 9you    |
| 9you    | shanghai |    3 | 9you    |
| baidu    | hangzhou |    3 | 9you    |
| tx     | hangzhou |    3 | 9you    |
| 163     | hangzhou |    4 | 9you    |
| 9you    | shanghai |    4 | 9you    |
| baidu    | hangzhou |    4 | 9you    |
| tx     | hangzhou |    4 | 9you    |
| 163     | hangzhou |    5 | 9you    |
| 9you    | shanghai |    5 | 9you    |
| baidu    | hangzhou |    5 | 9you    |
| tx     | hangzhou |    5 | 9you    |
| 163     | hangzhou |    6 | tx     |
| 9you    | shanghai |    6 | tx     |
| baidu    | hangzhou |    6 | tx     |
| tx     | hangzhou |    6 | tx     |
+-------------+----------+----------+-------------+

登录后复制

INNER JOIN联接(内联接)

INNER JOIN比CROSS JOIN强大的一点在于,INNER JOIN可以根据一些过滤条件来匹配表之间的数据。在SQL逻辑查询语句执行的前三步中,INNER JOIN会执行第一步和第二步;即没有第三步,不添加外部行,这是INNER JOIN和接下来要说的OUTER JOIN的最大区别之一。

现在来看看使用INNER JOIN来查询一下:

select * 
from table1 
inner join table2 
on table1.customer_id=table2.customer_id;

登录后复制

就会得到以下结果:

+-------------+----------+----------+-------------+
| customer_id | city   | order_id | customer_id |
+-------------+----------+----------+-------------+
| 163     | hangzhou |    1 | 163     |
| 163     | hangzhou |    2 | 163     |
| 9you    | shanghai |    3 | 9you    |
| 9you    | shanghai |    4 | 9you    |
| 9you    | shanghai |    5 | 9you    |
| tx     | hangzhou |    6 | tx     |
+-------------+----------+----------+-------------+

登录后复制

对于INNER JOIN来说,如果没有使用ON条件的过滤,INNER JOIN和CROSS JOIN的效果是一样的。当在ON中设置的过滤条件列具有相同的名称,我们可以使用USING关键字来简写ON的过滤条件,这样可以简化sql语句,例如:

select * from table1 inner join table2 using(customer_id);

登录后复制

在实际编写sql语句时,我们都可以省略掉INNER关键字,例如:

select * 
from table1 
join table2 
on table1.customer_id=table2.customer_id;

登录后复制

但是,请记住,这还是INNER JOIN。
OUTER JOIN联接(外联接)

哦,记得有一次参加面试,还问我这个问题来着,那在这里再好好的总结一下。通过OUTER JOIN,我们可以按照一些过滤条件来匹配表之间的数据。OUTER JOIN的结果集等于INNER JOIN的结果集加上外部行;也就是说,在使用OUTER JOIN时,SQL逻辑查询语句执行的前三步,都会执行一遍。关于如何添加外部行,请参考《SQL逻辑查询语句执行顺序》这篇文章中的添加外部行部分内容。

MySQL数据库支持LEFT OUTER JOIN和RIGHT OUTER JOIN,与INNER关键字一样,我们可以省略OUTER关键字。对于OUTER JOIN,同样的也可以使用USING来简化ON子句。所以,对于以下sql语句:

select * 
from table1 
left outer join table2 
on table1.customer_id=table2.customer_id;

登录后复制

我们可以简写成这样:

select * 
from table1 
left join table2 
using(customer_id);

登录后复制
登录后复制

但是,与INNER JOIN还有一点区别是,对于OUTER JOIN,必须指定ON(或者using)子句,否则MySQL数据库会抛出异常。
NATURAL JOIN联接(自然连接)

NATURAL JOIN等同于INNER(OUTER) JOIN与USING的组合,它隐含的作用是将两个表中具有相同名称的列进行匹配。同样的,NATURAL LEFT(RIGHT) JOIN等同于LEFT(RIGHT) JOIN与USING的组合。比如:

select * 
from table1 
join table2 
using(customer_id);

登录后复制

select * 
from table1 
natural join table2;

登录后复制

等价。

在比如:

select * 
from table1 
left join table2 
using(customer_id);

登录后复制
登录后复制

select * 
from table1 
natural left join table2;

登录后复制

等价。
STRAIGHT_JOIN联接

STRAIGHT_JOIN并不是一个新的联接类型,而是用户对sql优化器的控制,其等同于JOIN。通过STRAIGHT_JOIN,MySQL数据库会强制先读取左边的表。举个例子来说,比如以下sql语句:

explain select * 
from table1 join table2 
on table1.customer_id=table2.customer_id;

登录后复制

它的主要输出部分如下:

+----+-------------+--------+------+---------------+
| id | select_type | table | type | possible_keys |
+----+-------------+--------+------+---------------+
| 1 | SIMPLE   | table2 | ALL | NULL     |
| 1 | SIMPLE   | table1 | ALL | PRIMARY    |
+----+-------------+--------+------+---------------+

登录后复制

我们可以很清楚的看到,MySQL是先选择的table2表,然后再进行的匹配。如果我们指定STRAIGHT_JOIN方式,例如:

explain select * 
from table1 straight_join table2 
on table1.customer_id=table2.customer_id;

登录后复制

上述语句的主要输出部分如下:

+----+-------------+--------+------+---------------+
| id | select_type | table | type | possible_keys |
+----+-------------+--------+------+---------------+
| 1 | SIMPLE   | table1 | ALL | PRIMARY    |
| 1 | SIMPLE   | table2 | ALL | NULL     |
+----+-------------+--------+------+---------------+

登录后复制

可以看到,当指定STRAIGHT_JOIN方式以后,MySQL就会先选择table1表,然后再进行的匹配。

那么就有读者问了,这有啥好处呢?性能,还是性能。由于我这里测试数据比较少,大进行大量数据的访问时,我们指定STRAIGHT_JOIN让MySQL先读取左边的表,让MySQL按照我们的意愿来完成联接操作。在进行性能优化时,我们可以考虑使用STRAIGHT_JOIN。
多表联接

在上面的所有例子中,我都是使用的两个表之间的联接,而更多时候,我们在工作中,可能不止要联接两张表,可能要涉及到三张或者更多张表的联接查询操作。

对于INNER JOIN的多表联接查询,可以随意安排表的顺序,而不会影响查询的结果。这是因为优化器会自动根据成本评估出访问表的顺序。如果你想指定联接顺序,可以使用上面总结的STRAIGHT_JOIN。

而对于OUTER JOIN的多表联接查询,表的位置不同,涉及到添加外部行的问题,就可能会影响最终的结果。
总结

这是MySQL中联接操作的全部内容了,内容虽多,但是都还比较简单,结合文章中的例子,再自己实际操作一遍,完全可以搞定的。这一篇文章就这样了。

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

仓库:如何复兴队友
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

PHP 的大数据结构处理技巧 PHP 的大数据结构处理技巧 May 08, 2024 am 10:24 AM

大数据结构处理技巧:分块:分解数据集并分块处理,减少内存消耗。生成器:逐个产生数据项,无需加载整个数据集,适用于无限数据集。流:逐行读取文件或查询结果,适用于大文件或远程数据。外部存储:对于超大数据集,将数据存储在数据库或NoSQL中。

如何优化 PHP 中的 MySQL 查询性能? 如何优化 PHP 中的 MySQL 查询性能? Jun 03, 2024 pm 08:11 PM

可以通过以下方式优化MySQL查询性能:建立索引,将查找时间从线性复杂度降至对数复杂度。使用PreparedStatements,防止SQL注入并提高查询性能。限制查询结果,减少服务器处理的数据量。优化连接查询,包括使用适当的连接类型、创建索引和考虑使用子查询。分析查询,识别瓶颈;使用缓存,减少数据库负载;优化PHP代码,尽量减少开销。

如何在 PHP 中使用 MySQL 备份和还原? 如何在 PHP 中使用 MySQL 备份和还原? Jun 03, 2024 pm 12:19 PM

在PHP中备份和还原MySQL数据库可通过以下步骤实现:备份数据库:使用mysqldump命令转储数据库为SQL文件。还原数据库:使用mysql命令从SQL文件还原数据库。

如何使用 PHP 插入数据到 MySQL 表中? 如何使用 PHP 插入数据到 MySQL 表中? Jun 02, 2024 pm 02:26 PM

如何将数据插入MySQL表中?连接到数据库:使用mysqli建立与数据库的连接。准备SQL查询:编写一个INSERT语句以指定要插入的列和值。执行查询:使用query()方法执行插入查询,如果成功,将输出一条确认消息。

如何修复 MySQL 8.4 上的 mysql_native_password 未加载错误 如何修复 MySQL 8.4 上的 mysql_native_password 未加载错误 Dec 09, 2024 am 11:42 AM

MySQL 8.4(截至 2024 年的最新 LTS 版本)中引入的主要变化之一是默认情况下不再启用“MySQL 本机密码”插件。此外,MySQL 9.0完全删除了这个插件。 此更改会影响 PHP 和其他应用程序

如何在 PHP 中使用 MySQL 存储过程? 如何在 PHP 中使用 MySQL 存储过程? Jun 02, 2024 pm 02:13 PM

要在PHP中使用MySQL存储过程:使用PDO或MySQLi扩展连接到MySQL数据库。准备调用存储过程的语句。执行存储过程。处理结果集(如果存储过程返回结果)。关闭数据库连接。

如何使用 PHP 创建 MySQL 表? 如何使用 PHP 创建 MySQL 表? Jun 04, 2024 pm 01:57 PM

使用PHP创建MySQL表需要以下步骤:连接到数据库。创建数据库(如果不存在)。选择数据库。创建表。执行查询。关闭连接。

oracle数据库和mysql的区别 oracle数据库和mysql的区别 May 10, 2024 am 01:54 AM

Oracle数据库和MySQL都是基于关系模型的数据库,但Oracle在兼容性、可扩展性、数据类型和安全性方面更胜一筹;而MySQL则侧重速度和灵活性,更适合小到中等规模的数据集。①Oracle提供广泛的数据类型,②提供高级安全功能,③适合企业级应用程序;①MySQL支持NoSQL数据类型,②安全性措施较少,③适合小型到中等规模应用程序。

See all articles