关系型数据库,免不了表之间存在各种引用与关联。这些关联是通过主键与外键搭配来形成的。所以,取数据时,很大情况下单张表无法满足需求,额外的数据则需要将其他表加入到查询中来,这便是 JOIN 关键字完成的操作。

  • MySQL 中 JOIN, CROSS JOININNER JOIN 三者语法功能上相同,可互换,而 SQL 标准中,INNER JOIN 需要搭配 ON 语句。

多表联合查询时,可省略 JOIN 关键字,以逗号分隔多张表,此时默认会当作 INNER JOIN 来处理。比如,

SELECT table1.*,
table2.*
FROM table1,
table2;

等效于:

SELECT table1.*,
table2.*
FROM table1
INNER JOIN table2;
  • 但这种通过逗号隐式指定的联表形式其优先级要低于直接通过关键字(INNER JOIN, CROSS JOIN, LEFT JOIN)指定的形式。所以 t1, t2 JOIN t3 会被解析成 (t1, (t2 JOIN t3)) 而不是 ((t1, t2) JOIN t3)

需要注意的是,当逗号形式与其他联表关键词结合时,在指定了联表条件,比如通过 ON 条件时,会报错。

  • ON 指定的联表条件其语法同 WHERE,所有后者可接受的表达式都可用于 ON。两者看起来功能上雷同,ON 一般用于指定联表条件,即表之间怎么被联合,而 WHERE 则用于过滤结果。

  • LEFT JOIN 时,右边表中不满足 ONUSING 指定的条件时,会在结果中以 NULL 呈现。

SELECT left_tbl.*
FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
WHERE right_tbl.id IS NULL;

通过此方法可方便地过滤出右边表中不符合条件的记录。

  • 联表查询时可为每张参与进来的表指定别名,方便在其他表达式中引用。两种方式,一个是通过 AS 关键字 tbl_name AS alias_name,另一种是直接在表名后面跟上别名,tbl_name alias_name
SELECT t1.name, t2.salary
FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name; SELECT t1.name, t2.salary

FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;

一条查询语句中的子查询必需取一个别名,这样才能在其他表达式中引用。

SELECT * FROM (SELECT 1, 2, 3) AS t1;
  • USING(join_column_list) 语句指定两个表中均包含的列,查询时只针对这里指定的列进行比较。
a LEFT JOIN b USING (c1, c2, c3)
  • NATURAL [LEFT] JOININNER JOINLEFT JOIN 配合使用了 USING 指定表中所有列的情况等效。

  • RIGHT JOINLEFT JOIN 类似,只是最终结果是依据右边表,将左边表中不符合的在结果中以 NULL 呈现。为了方便在不同数据库间迁移,推荐始终使用 LEFT JOIN

一些 JOIN 示例:

SELECT * FROM table1, table2;

SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id;

SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id;

SELECT * FROM table1 LEFT JOIN table2 USING (id);

SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id

LEFT JOIN table3 ON table2.id = table3.id;
  • NATURAL JOIN 的结果中不会有重复的列。因为其与 USING 雷同,所以 USING 时也没有复杂的列。

考察下面的示例:

CREATE TABLE t1 (i INT, j INT);
CREATE TABLE t2 (k INT, j INT);
INSERT INTO t1 VALUES(1, 1);
INSERT INTO t2 VALUES(1, 1);
SELECT * FROM t1 NATURAL JOIN t2;
SELECT * FROM t1 JOIN t2 USING (j);

查询结果:

+------+------+------+
| j | i | k |
+------+------+------+
| 1 | 1 | 1 |
+------+------+------+
+------+------+------+
| j | i | k |
+------+------+------+
| 1 | 1 | 1 |
+------+------+------+

结果中同名的列只出现一次,且都是值相同的那些记录。

通过向两表中插入一条新记录,令它们的 j 不相同,再进行测试。

mysql> INSERT INTO t1 VALUES(2, 2);
Query OK, 1 row affected (0.00 sec) mysql> INSERT INTO t2 VALUES(2, 3);

Query OK, 1 row affected (0.00 sec) mysql> select * from t1 natural join t2;

+------+------+------+

| j | i | k |

+------+------+------+

| 2 | 2 | 1 |

+------+------+------+

1 row in set (0.00 sec)
  • USINGON 作为条件时其他限制的联合条件是一样的,可互相转换。但在 SELECT * 返回结果时,还是有差异的。前者只在 USING 中指定的列中返回合并后的结果,后者则针对的是表中所有列。
a LEFT JOIN b USING (c1, c2, c3)
a LEFT JOIN b ON a.c1 = b.c1 AND a.c2 = b.c2 AND a.c3 = b.c3

USING 情况下的返回:

COALESCE(a.c1, b.c1), COALESCE(a.c2, b.c2), COALESCE(a.c3, b.c3)

ON 的返回:

a.c1, a.c2, a.c3, b.c1, b.c2, b.c3
  • ON 语句中只能引用其操作表(operands)中的表。
CREATE TABLE t1 (i1 INT);
CREATE TABLE t2 (i2 INT);
CREATE TABLE t3 (i3 INT);

针对上面的表,以下查询会报错:

mysql> SELECT * FROM t1 JOIN t2 ON (i1 = i3) JOIN t3;
ERROR 1054 (42S22): Unknown column 'i3' in 'on clause'

而以下查询则可以:

mysql> SELECT * FROM t1 JOIN t2 JOIN t3 ON (i1 = i3);
Empty set (0.00 sec)

因为此时 t3ON 语句的操作范围内了。

相关资源

MySQL 联表查询的更多相关文章

  1. (转)MySQL联表查询

    资料源于网络   一.内联结.外联结.左联结.右联结的含义及区别在SQL标准中规划的(Join)联结大致分为下面四种:1.内联结:将两个表中存在联结关系的字段符合联结关系的那些记录形成记录集的联结.2 ...

  2. [MySQL] MySQL联表查询的执行顺序优化查询

    SELECT t4.orgName, t3.projectName, t3.Partner, t1.type, COUNT(DISTINCT t1.imei) AS count FROM `t_tem ...

  3. Linux mysql 联表查询

    在rhce考试题中,第21.22题为数据库查询题 题目: 在system1上创建一个Maria DB数据库,名为Contacts,要求: 数据库应该包含来自数据库users.mdb的内容,数据库只能被 ...

  4. 了解MySQL联表查询中的驱动表,优化查询,以小表驱动大表

    一.为什么要用小表驱动大表 1.驱动表的定义 当进行多表连接查询时, [驱动表] 的定义为: 1)指定了联接条件时,满足查询条件的记录行数少的表为[驱动表] 2)未指定联接条件时,行数少的表为[驱动表 ...

  5. 【explain】MySQL联表查询中的驱动表

    写在前面 1.不要求每个人一定理解 联表查询(join/left join/inner join等)时的mysql运算过程 2.不要求每个人一定知道线上(现在或未来)哪张表数据量大,哪张表数据量小 3 ...

  6. mysql联表查询,使用phpStudy自带的

    一.内联结.外联结.左联结.右联结的含义及区别在SQL标准中规划的(Join)联结大致分为下面四种:1.内联结:将两个表中存在联结关系的字段符合联结关系的那些记录形成记录集的联结.2.外联结:分为外左 ...

  7. mysql联表查询

    2.1 内连接 select a.*,b.* FROM  a INNER join  b  ON a.id = b.id;  查出所有 或者 select a.*,b.* FROM a join b ...

  8. [慢查优化]联表查询注意谁是驱动表 & 你搞不清楚谁join谁更好时请放手让mysql自行判定

    写在前面的话: 不要求每个人一定理解 联表查询(join/left join/inner join等)时的mysql运算过程: 不要求每个人一定知道线上(现在或未来)哪张表数据量大,哪张表数据量小: ...

  9. Mysql数据库表排序规则不一致导致联表查询,索引不起作用问题

    Mysql数据库表排序规则不一致导致联表查询,索引不起作用问题 表更描述: 将mysql数据库中的worktask表添加ishaspic字段. 具体操作:(1)数据库worktask表新添是否有图片字 ...

随机推荐

  1. ansible执行带有环境变量的脚本不生效

    1背景 jenkins发布时,使用ansible执行远程主机上的启动tomcat脚本发现不生效,启动tomcat的脚本中有环境变量. ansible主机为:172.16.35.8 tomcat服务器为 ...

  2. PHP 实现精确统计在线人数功能

    有需要学习交流的友人请加入交流群的咱们一起,有问题一起交流,一起进步!前提是你是学技术的.感谢阅读! 点此加入该群​jq.qq.com PHP对session对象的封装的很好,根据HTTP协议,每个范 ...

  3. CSS属性继承

    在CSS中有一些属性是可以继承的,跟继承家产一样,哎,一代一代的往下传,而有些属性就比较惨了,不能继承,只能自己来设置. 我简略的总结了一下一些可以继承和不可以继承的属性 可继承 1.字体系列属性:f ...

  4. vue 客户端渲染和服务端渲染

    参考链接 https://www.cnblogs.com/tiedaweishao/p/6644267.html

  5. Elasticsearch从入门到放弃:索引基本使用方法

    前文我们提到,Elasticsearch的数据都存储在索引中,也就是说,索引相当于是MySQL中的数据库.是最基础的概念.今天分享的也是关于索引的一些常用的操作. 创建索引 curl -X PUT & ...

  6. vue v-if和v-show的区别

    其中v-if依赖于控制DOM节点,而v-show是依赖于控制DOM节点的display属性. 当v-show传入的值为true时,对应DOM元素的display的值为block之类的,反之为false ...

  7. 剑指offer 24:二叉搜索树的后序遍历序列

    题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 解题思路 后序遍历,顾名思义根节点位于尾部,故可将 ...

  8. python数据库模块

    安装数据库 [mariadb] name = MariaDB baseurl = http://yum.mariadb.org/10.3/centos7-amd64 gpgkey=https://yu ...

  9. MySQL基础之数据管理【4】

    外键约束的使用(只有InnoDB存储引擎支持外键) create table news_cate( id tinyint unsigned auto_increment key comment '编号 ...

  10. [20191119]探究ipcs命令输出.txt

    [20191119]探究ipcs命令输出.txt $ man ipcsIPCS(8)                    Linux Programmer's Manual              ...