Mysql Left Join/IS NULL如何消除一个表中存在而另一个表中不存在的记录?
我很难理解为什么Mysql Left Join/IS NULL如何消除一个表中存在而另一个表中不存在的记录?,mysql,sql,left-join,isnull,Mysql,Sql,Left Join,Isnull,我很难理解为什么LEFT JOIN/为NULL会删除一个表中的记录而不是另一个表中的记录。 这里有一个例子 SELECT l.id, l.value FROM t_left l LEFT JOIN t_right r ON r.value = l.value WHERE r.value IS NULL 为什么r.value=NULL应该删除记录?我不明白。我知道我错过了一些非常基本的东西,但目前我甚至不能理解这个基本的东西。如果有人向我详细解释,我将不胜感激 我想要一个非
LEFT JOIN
/为NULL
会删除一个表中的记录而不是另一个表中的记录。
这里有一个例子
SELECT l.id, l.value
FROM t_left l
LEFT JOIN t_right r
ON r.value = l.value
WHERE r.value IS NULL
为什么r.value=NULL
应该删除记录?我不明白。我知道我错过了一些非常基本的东西,但目前我甚至不能理解这个基本的东西。如果有人向我详细解释,我将不胜感激
我想要一个非常基本的解释
SELECT * FROM a LEFT JOIN b ON a.v = b.v ... WHERE b.id IS NULL
这是超简单的逻辑:
- 从表“a”中选择
- 联接表“b”(如果存在匹配行-在a.v=b.v上,否则使用NULL作为值)
- 其中条件:如果缺少某些内容(b.id为NULL)=OK
如果l.值没有r.值,则r为空
r、 value is null将为true在您的示例中,结果将是
t\u left
的每个记录,以及t\u right
的每个匹配记录,它们都具有相同的值
。如果不匹配,则给出NULL
值,而不是t\u right
中的值其中r.value为null
通过检测那些null
值,简单地消除匹配的行
实际上是说“给我t\u left
中与t\u right
中的行不匹配的行”
右连接
执行与左连接
相反的顺序 这是基于内部连接
和左侧连接
之间的差异。使用内部联接时,结果仅包含两个表之间匹配的行(基于on
条件)
但是,当您使用左联接时,
,第一个表中所有与第二个表中不匹配的行的结果中也会有行。在这些情况下,第二个表中的所有结果列都以NULL
作为占位符填充
其中r.value为NULL的测试然后与这些行匹配。因此,最终结果只包含不匹配的行。LEFT JOIN获取左侧的值,并尝试通过上指定的列匹配左侧的表。如果未找到匹配项,则将右侧表的列解释为NULL。因此,只有那些在右表中找不到匹配项的记录才会被IS NULL操作符选中。首先,左连接声明将包括左表中的所有记录,并且只有那些在右表中匹配的记录
假设你抽屉里有一只<代码>红色<代码>,<代码>蓝色<代码>和<代码>绿色<代码>袜子,而你的朋友只有一只<代码>红色<代码>,<代码>黄色<代码>和<代码>蓝色<代码>,从你的抽屉向你的朋友左连,你抽屉里的袜子就会全部退出来(<代码>红色<代码>,<代码>蓝色<代码>和<代码>绿色<代码>)并且只匹配你朋友的(红色
和蓝色
)
现在,IS NULL部分表示您希望查看抽屉中的所有袜子,其中朋友抽屉中没有匹配的配对伙伴,因此从所有袜子中,唯一缺少配对的是绿色袜子。这句话:
SELECT l.id, l.value
FROM t_left l
LEFT JOIN t_right r
ON r.value = l.value
将把t\u left
表中的所有元素连接到t\u right
表中的所有元素。正如您现在可能会看到的那样,在内部联接中,只会显示与两个表匹配的行,因此t\u left
可能比所有可能的行都少。在LEFT JOIN
中,您拥有t\u LEFT
表中的所有行,以及t\u right
中匹配的行(如果可以合并)。那么,如果t_左边的行与t_右边的行不匹配,会发生什么呢?t_right表中应该包含数据的所有字段都将用空值填充。因此,如果您仅从右表中选择NULL
值,您将发现t_left
表中的所有值在右表中没有匹配项,XD这可以用以下内容解释
mysql> select * from table1 ;
+------+------+
| id | val |
+------+------+
| 1 | 10 |
| 2 | 30 |
| 3 | 40 |
+------+------+
3 rows in set (0.00 sec)
mysql> select * from table2 ;
+------+------+
| id | t1id |
+------+------+
| 1 | 1 |
| 2 | 2 |
+------+------+
2 rows in set (0.00 sec)
此处table1.id table2.t1id
现在,当我们使用连接键进行左连接时,如果左表是table1,那么它将从table1获取所有数据,而table2上的非匹配记录中的数据将设置为null
mysql> select t1.* , t2.t1id from table1 t1
left join table2 t2 on t2.t1id = t1.id ;
+------+------+------+
| id | val | t1id |
+------+------+------+
| 1 | 10 | 1 |
| 2 | 30 | 2 |
| 3 | 40 | NULL |
+------+------+------+
3 rows in set (0.00 sec)
请注意,table1.id=3在table2中没有值,因此将其设置为null
应用where条件时,它将执行进一步过滤
mysql> select t1.* , t2.t1id from table1 t1
left join table2 t2 on t2.t1id = t1.id where t2.t1id is null;
+------+------+------+
| id | val | t1id |
+------+------+------+
| 3 | 40 | NULL |
+------+------+------+
1 row in set (0.00 sec)
Left join
提供左表中的所有记录。如果右表中缺少左表中的任意键,则“所有右表”列将为空,但所有左表值都将存在
这是内部联接和左/右联接的基本区别
所以,当您执行'r.value=null'时,您将从左侧获得这些记录,而右侧表中并没有匹配的键
HTH.这是一个简单的左联基金。。。。。
下面的查询从左表获取所有记录,如果不匹配,则从右表获取匹配的记录,然后返回NUll值。最后,使用where条件过滤数据,该条件返回的值在左表中,但在右表中不
SELECT l.id, l.value
FROM t_left l
LEFT JOIN t_right r
ON r.value = l.value
WHERE r.value IS NULL
假设r-table是雇员,r_-table是计算机。有些员工没有电脑。有些计算机尚未分配给任何人
内部联接:
SELECT l.*, r.*
FROM employees l
JOIN computers r
ON r.id = l.comp_id
提供拥有计算机的所有员工的列表,以及为每个员工分配的计算机的相关信息。没有电脑的员工将不会出现在此列表中
左连接:
SELECT l.*, r.*
FROM employees l
LEFT JOIN computers r
ON r.id = l.comp_id
提供所有员工的列表。有电脑的员工将显示电脑信息。没有计算机的员工将显示为空,而不是计算机信息
最后
SELECT l.*, r.*
FROM employees l
LEFT JOIN computers r
ON r.id = l.comp_id
WHERE r.id IS NULL
左与右连接
SELECT l.*
FROM ...
CREATE TABLE employees
( id INT NOT NULL PRIMARY KEY,
name VARCHAR(20),
comp_id INT);
INSERT INTO employees (id, name, comp_id) VALUES (1, 'Becky', 1);
INSERT INTO employees (id, name, comp_id) VALUES (2, 'Anne', 7);
INSERT INTO employees (id, name, comp_id) VALUES (3, 'John', 3);
INSERT INTO employees (id, name) VALUES (4, 'Bob');
CREATE TABLE computers
( id INT NOT NULL PRIMARY KEY,
os VARCHAR(20) );
INSERT INTO computers (id, os) VALUES (1,'Windows 7');
INSERT INTO computers (id, os) VALUES (2,'Windows XP');
INSERT INTO computers (id, os) VALUES (3,'Unix');
INSERT INTO computers (id, os) VALUES (4,'Windows 7');