深入理解mysql之left join 使用详解

深入理解mysql之left join 使用详解

即使你认为自己已对关系型数据库的左连接理解深刻,但我敢打赌,这篇文章肯定能让你学会点东西

在…上子句与在哪里子句的不同一种更好地理解带有在哪里.为空子句的复杂匹配条件的简单方法匹配条件与哪里条件的不同

关于“答向左加入B条件表达式"的一点提醒

在…上条件(“答向左连接B条件表达式"中的开)用来决定如何从B表中检索数据行。

如果B表中没有任何一行数据匹配在…上的条件,将会额外生成一行所有列为空的数据

在匹配阶段在哪里子句的条件都不会被使用。仅在匹配阶段完成以后,在哪里子句条件才会被使用。它将从匹配阶段产生的数据中检索过滤。

让我们看一个LFET连接示例:

关系型数据库创建表` product `(` id ` int(10)unsigned NOT NULL AUTO _ INCREMENT,` amount ` int(10)unsigned DEFAULT NULL,PRIMARY KEY(` id `))ENGINE=MyISAM AUTO _ INCREMENT=5 DEFAULT CHARSET=latin1

关系型数据库创建表` product _ details `(` id ` int(10)unsigned NOT NULL,` weight ` int(10)unsigned DEFAULT NULL,` exist ` int(10)unsigned DEFAULT NULL,PRIMARY KEY(` id `))ENGINE=MyISAM DEFAULT CHARSET=latin1

mysql插入产品(id,数量)值(1,100)、(2,200)、(3,300)、(4,400);查询正常,4行受影响(0.00秒)记录:4个重复项:0个警告:0个

MySQL INSERT INTO product _ details(id、重量、存在)值(2,22,0),(4,44,1),(5,55,0),(6,66,1);查询正常,4行受影响(0.00秒)记录:4个重复项:0个警告:0个

mysql SELECT * FROM product - | id |金额|-| 1 | 100 | | 2 | 200 | | 3 | 300 | | 4 | 400 | - 集合中的四行(0.00秒)

MySQL SELECT * FROM product _ details;-| id | weight | exist |-| 2 | 22 | 0 | | 4 | 44 | 1 | | 5 | 55 | 0 | | 6 | 66 | 1 |-集合中的四行(0.00秒)

MySQL SELECT * FROM product LEFT JOIN product _ details ON(product。id=产品详细信息。id);-| id | amount | id | weight | exist |-| 1 | 100 | NULL | NULL | NULL | | 2 | 200 | 2 | 22 | 0 | | 3 | 300 | NULL | NULL | NULL | | 4 | 400 | 4 | 44 | 1 |-集合中的四行(0.00秒)

在…上子句和在哪里子句有什么不同?

一个问题:下面两个查询的结果集有什么不同么?

1.SELECT * FROM product LEFT JOIN product _ details ON(product。id=产品详细信息。id)和产品详细信息。id=2;2.SELECT * FROM product LEFT JOIN product _ details ON(product。id=产品详细信息。id)其中产品_详情。id=2;

用例子来理解最好不过了:

MySQL SELECT * FROM product LEFT JOIN product _ details ON(product。id=产品详细信息。id)和产品_详情。id=2;-| id | amount | id | weight | exist |-| 1 | 100 | NULL | NULL | NULL | | 2 | 200 | 2 | 22 | 0 | | 3 | 300 | NULL | NULL | NULL | | 4 | 400 | NULL | NULL | NULL |-集合中的四行(0.00秒)

MySQL SELECT * FROM product LEFT JOIN product _ details ON(product。id=产品详细信息。id)其中产品_详情。id=2;- - - | id |金额| id |重量|存在| - | 2 | 200 | 2 | 22 | 0 | - 集合中的一行(0.01秒)

第一条查询使用在…上条件决定了从左连接的产品_详情表中检索符合的所有数据行。

第二条查询做了简单的左连接,然后使用在哪里子句从左连接的数据中过滤掉不符合条件的数据行。

再来看一些示例:

MySQL MySQL SELECT * FROM product LEFT JOIN product _ details ON product。id=产品详细信息。身份证明(identification)和product . amount=100-| id | amount | id | weight | exist |-| 1 | 100 | NULL | NULL | NULL | | 2 | 200 | NULL | NULL | NULL | | 3 | 300 | NULL | NULL | NULL | | NULL | | 4 | 400 | NULL | NULL | NULL |-集合中的四行(0.00秒)

所有来自产品表的数据行都被检索到了,但没有在产品_详情表中匹配到记录(product.id=产品详细信息. id和产品数量=100条件并没有匹配到任何数据)

MySQL SELECT * FROM product LEFT JOIN product _ details ON(product。id=产品详细信息。id)和product . amount=200-| id | amount | id | weight | exist |-| 1 | 100 | NULL | NULL | NULL | | 2 | 200 | 2 | 22 | 0 | | 3 | 300 | NULL | NULL | NULL | | 4 | 400 | NULL | NULL | NULL |-集合中的四行(0.01秒)

同样,所有来自产品表的数据行都被检索到了,有一条数据匹配到了。

使用在哪里.为空子句的左连接

当你使用在哪里.为空子句时会发生什么呢?

如前所述,在哪里条件查询发生在匹配阶段之后,这意味着在哪里.为空子句将从匹配阶段后的数据中过滤掉不满足匹配条件的数据行。

纸面上看起来很清楚,但是当你在在…上子句中使用多个条件时就会感到困惑了。

我总结了一种简单的方式来理解上述情况:

将为空作为否定匹配条件使用!(一)和B)==!a或者!B逻辑判断

看看下面的示例:

MySQL SELECT a . * FROM product a LEFT JOIN product _ details b ON a . id=b . id和b .体重!=44且b .存在=0,其中身份证为空;- | id |金额|-| 1 | 100 | | 3 | 300 | | 4 | 400 | - 集合中的3行(0.00秒)

让我们检查一下在…上匹配子句:

(a.id=b.id)和(b .重量!=44)和(b.exist=0)

我们可以把为空子句看作是否定匹配条件。

这意味着我们将检索到以下行:

!(存在(b.id等于a.id)和b .体重!=44且b.exist=0)!存在(b.id等于a.id) ||!(b。重量!=44) || !(b.exist=0)!存在(b.id等于a.id) || b.weight=44 || b.exist=1

就像在C语言中的逻辑和和逻辑运筹学表达式一样,其操作数是从左到右求值的。如果第一个参数做够判断操作结果,那么第二个参数便不会被计算求值(短路效果)

看看别的示例:

MySQL SELECT a . * FROM product a LEFT JOIN product _ details b ON a . id=b . id和b .体重!=44且b .存在=1,其中身份证为空;- | id |金额|-| 1 | 100 | | 2 | 200 | | 3 | 300 | | 4 | 400 | - 集合中的四行(0.00秒)

匹配条件与哪里条件之战

如果你吧基本的查询条件放在在…上子句中,把剩下的否定条件放在在哪里子句中,那么你会获得相同的结果。

例如,你可以不这样写:

SELECT a . * FROM product a LEFT JOIN product _ details bON a . id=b . id和b .体重!=44且b.exist=,其中身份证为空;

你可以这样写:

SELECT a . * FROM product a LEFT JOIN product _ details bON a . id=b . id其中b .身份证为空或重量=44或b .存在=1;

MySQL SELECT a . * FROM product a LEFT JOIN product _ details b ON a . id=b . id其中b .身份证为空或者重量=44或者b .存在=1;- | id |金额|-| 1 | 100 | | 3 | 300 | | 4 | 400 | - 集合中的3行(0.00秒)

你可以不这样写:

SELECT a . * FROM product a LEFT JOIN product _ details bON a . id=b . id和b .体重!=44和乙。存在!=0,其中身份证为空;

可以这样写:

SELECT a . * FROM product a LEFT JOIN product _ details bON a . id=b . id其中b .身份证为空或重量=44或b .存在=0;

MySQL SELECT a . * FROM product a LEFT JOIN product _ details b ON a . id=b . id其中b .身份证为空或者重量=44或者b .存在=0;- | id |金额|-| 1 | 100 | | 2 | 200 | | 3 | 300 | | 4 | 400 | - 集合中的四行(0.00秒)

这些查询真的效果一样?

如果你只需要第一个表中的数据的话,这些查询会返回相同的结果集。有一种情况就是,如果你从左连接的表中检索数据时,查询的结果就不同了。

如前所属,在哪里子句是在匹配阶段之后用来过滤的。

例如:

MySQL SELECT * FROM product a LEFT JOIN product _ details b ON a . id=b . id和b .体重!=44且b .存在=1,其中身份证为空;-| id | amount | id | weight | exist |-| 1 | 100 | NULL | NULL | NULL | | 2 | 200 | NULL | NULL | NULL | | 3 | 300 | NULL | NULL | NULL | | NULL | | NULL | | 4 | 400 | NULL | NULL | NULL |-集合中的四行(0.00秒)

MySQL SELECT * FROM product a LEFT JOIN product _ details b ON a . id=b . id其中b .身份证为空或者重量=44或者b .存在=0;-| id | amount | id | weight | exist |-| 1 | 100 | NULL | NULL | NULL | | 2 | 200 | 2 | 22 | 0 | | 3 | 300 | NULL | NULL | NULL | | 4 | 400 | 4 | 44 | 1 |-集合中的四行(0.00秒)

总附注:

如果你使用左连接来寻找在一些表中不存在的记录,你需要做下面的测试:在哪里部分的列名为空(其中列名列被定义为非空)、MYSQL在查询到一条匹配左连接条件后将停止搜索更多行(在一个特定的组合键下)。

深入理解mysql之left join 使用详解