MYSQL LEFT JOIN 的怪异行为

Posted 客家族_祖仙教_小凡仙

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MYSQL LEFT JOIN 的怪异行为相关的知识,希望对你有一定的参考价值。

理论 mysql的LEFT JOIN 有时候会变的不一样

如果LFET JOIN B WHERE 条件部分有B的条件,那么它跟主表不再是LEFT

JOIN ,而是变成了 INNER JOIN!

我们创建两个父子表

mysql> show create table children;+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Table    | Create Table                                                                                                                                                                                                                                                                                                                           |+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| children | CREATE TABLE `children` (  `ID` bigint unsigned NOT NULL AUTO_INCREMENT,  `NAME` varchar(45) DEFAULT NULL,  `SEX` char(1) DEFAULT NULL,  `AGE` tinyint DEFAULT NULL,  `FATHER_ID` bigint DEFAULT NULL,  PRIMARY KEY (`ID`)) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='孩子'   |+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+1 row in set (0.01 sec)
mysql> show create table FATHER;+--------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Table  | Create Table                                                                                                                                                                                                                                                              |+--------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| FATHER | CREATE TABLE `FATHER` (  `ID` bigint unsigned NOT NULL AUTO_INCREMENT,  `NAME` varchar(45) DEFAULT NULL,  `MONY` decimal(10,0) DEFAULT NULL,  PRIMARY KEY (`ID`)) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='父亲'   |+--------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+1 row in set (0.00 sec)

生成必要的数据

mysql> select * from FATHER;+----+--------+------+| ID | NAME   | MONY |+----+--------+------+|  1 | 王五   | 3000 ||  2 | 张三   | 3500 ||  3 | 李四   | 5000 ||  4 | 刘二   | 8000 ||  5 | 陈七   | 5500 ||  6 | 杨八   | 7500 |+----+--------+------+6 rows in set (0.00 sec)
mysql> select * from children;+----+-----------+------+------+-----------+| ID | NAME      | SEX  | AGE  | FATHER_ID |+----+-----------+------+------+-----------+|  1 | 王八      | 男   |   38 |         1 ||  2 | 王高      | 男   |   28 |         1 ||  3 | 王艳      | 女   |   18 |         1 ||  4 | 张雪      | 女   |   33 |         2 ||  5 | 张亮      | 男   |   25 |         2 ||  6 | 李贵      | 男   |   27 |         3 ||  7 | 李丽      | 女   |   25 |         3 ||  8 | 杨莉      | 女   |   23 |         6 ||  9 | 杨雪      | 女   |   22 |         6 || 10 | 杨七郎    | 男   |   35 |         6 |+----+-----------+------+------+-----------+10 rows in set (0.00 sec)

实验一   没有条件的时候

mysql> SELECT A.NAME,A.MONY,B.NAME,B.AGE,B.SEX    -> FROM books.FATHER A    -> LEFT JOIN books.children B ON A.ID=B.FATHER_ID    -> ORDER BY A.ID ASC;+--------+------+-----------+------+------+| NAME   | MONY | NAME      | AGE  | SEX  |+--------+------+-----------+------+------+| 王五   | 3000 | 王艳      |   18 | 女   || 王五   | 3000 | 王高      |   28 | 男   || 王五   | 3000 | 王八      |   38 | 男   || 张三   | 3500 | 张亮      |   25 | 男   || 张三   | 3500 | 张雪      |   33 | 女   || 李四   | 5000 | 李丽      |   25 | 女   || 李四   | 5000 | 李贵      |   27 | 男   || 刘二   | 8000 | NULL      | NULL | NULL || 陈七   | 5500 | NULL      | NULL | NULL || 杨八   | 7500 | 杨七郎    |   35 | 男   || 杨八   | 7500 | 杨雪      |   22 | 女   || 杨八   | 7500 | 杨莉      |   23 | 女   |+--------+------+-----------+------+------+12 rows in set (0.00 sec)

认为非常正常,没有孩子的要展现出来的!

执行计划也很正常

+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------------+| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                                      |+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------------+|  1 | SIMPLE      | A     | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    6 |   100.00 | Using temporary; Using filesort            ||  1 | SIMPLE      | B     | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   10 |   100.00 | Using where; Using join buffer (hash join) |+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------------+

实验二 带条件的

mysql> SELECT A.NAME,A.MONY,B.NAME,B.AGE,B.SEX    -> FROM books.FATHER A    -> LEFT JOIN books.children B ON A.ID=B.FATHER_ID    -> WHERE B.SEX='男'    -> ORDER BY A.ID ASC;+--------+------+-----------+------+------+| NAME   | MONY | NAME      | AGE  | SEX  |+--------+------+-----------+------+------+| 王五   | 3000 | 王八      |   38 | 男   || 王五   | 3000 | 王高      |   28 | 男   || 张三   | 3500 | 张亮      |   25 | 男   || 李四   | 5000 | 李贵      |   27 | 男   || 杨八   | 7500 | 杨七郎    |   35 | 男   |+--------+------+-----------+------+------+

主表的被屏蔽掉了,而执行计划是B表为主表,驱动表

详情见阅读原文

以上是关于MYSQL LEFT JOIN 的怪异行为的主要内容,如果未能解决你的问题,请参考以下文章

MYSQL LEFT JOIN 的怪异行为

MySQL 在同一张表上有 2 个 LEFT JOIN

使用 MySQL LEFT JOIN 删除行

LEFT JOIN 或 REGULAR JOIN,以及如何将 MySql 表与数组进行比较?需要表现!

Mysql - LEFT JOIN 比 INNER JOIN 快

mysql left join中where和on条件的区别