理解这个 SQL LEFT JOIN (with IS NULL) 例子
Understanding this SQL LEFT JOIN (with IS NULL) example
在数据库中,有一个 table 称为类别:
CREATE TABLE category(
category_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
parent INT DEFAULT NULL
);
创建它是为了制作相邻列表模型树。这是目前 table 中的内容:
在这个例子中(你可以在底部找到来源link),下面的sql代码用于获取[=47=中的"leaf"个元素],"leaf" 元素是 table 中没有任何其他行的行,在 "parent" 列中使用它们的 "category_id"。以下代码是 运行:
SELECT t1.name FROM
category AS t1 LEFT JOIN category as t2
ON t1.category_id = t2.parent
WHERE t2.category_id IS NULL;
前面SQL代码的结果给出了这个结果:
例如,table 中没有父列中值为 3 的行,因此 TUBE(category_id == 3)是一个 "leaf" 元素.
问题: 为什么 sql 代码在逻辑上给出了这个结果?我很高兴它确实如此,因为它正是我所需要的,但我无法理解它背后的原因。
示例来源:http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
每当您看到此模式时:
SELECT ...
FROM TableA
LEFT JOIN TableB ON TableA.column = TableB.column
WHERE TableB.id is null
思考:“在 TableA 中找到 TableB 中不存在的行。
您的查询意味着 "find categories that have no child"。如果您删除 WHERE
子句并向查询中添加更多列,则更容易理解:
SELECT t1.category_id,
t1.name,
t2.name AS ChildName
FROM category AS t1
LEFT JOIN category as t2 ON t1.category_id = t2.parent
以下是您的查询中发生的情况:
- 从
category
table 开始,将其别名为 t1
和 t2
。从现在开始我将引用别名。
- 对于
t1
中的每一行,查找 t2
中将 t1
行标识为其父行的所有记录
- 如果
t1
行没有子行,t2.category_id
将为空
- 我们只想筛选
t1
没有子项的行
我认为如果您重命名您的 table 别名会更容易看到发生了什么:
SELECT tparent.name
FROM category AS tparent
LEFT JOIN category as tchild
ON tparent.category_id = tchild.parent
WHERE tchild.category_id IS NULL;
现在可能更容易看出您要的是没有子项的所有父类别名称的列表 [tchild.category_id IS NULL]
在数据库中,有一个 table 称为类别:
CREATE TABLE category(
category_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
parent INT DEFAULT NULL
);
创建它是为了制作相邻列表模型树。这是目前 table 中的内容:
在这个例子中(你可以在底部找到来源link),下面的sql代码用于获取[=47=中的"leaf"个元素],"leaf" 元素是 table 中没有任何其他行的行,在 "parent" 列中使用它们的 "category_id"。以下代码是 运行:
SELECT t1.name FROM
category AS t1 LEFT JOIN category as t2
ON t1.category_id = t2.parent
WHERE t2.category_id IS NULL;
前面SQL代码的结果给出了这个结果:
例如,table 中没有父列中值为 3 的行,因此 TUBE(category_id == 3)是一个 "leaf" 元素.
问题: 为什么 sql 代码在逻辑上给出了这个结果?我很高兴它确实如此,因为它正是我所需要的,但我无法理解它背后的原因。
示例来源:http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
每当您看到此模式时:
SELECT ...
FROM TableA
LEFT JOIN TableB ON TableA.column = TableB.column
WHERE TableB.id is null
思考:“在 TableA 中找到 TableB 中不存在的行。
您的查询意味着 "find categories that have no child"。如果您删除 WHERE
子句并向查询中添加更多列,则更容易理解:
SELECT t1.category_id,
t1.name,
t2.name AS ChildName
FROM category AS t1
LEFT JOIN category as t2 ON t1.category_id = t2.parent
以下是您的查询中发生的情况:
- 从
category
table 开始,将其别名为t1
和t2
。从现在开始我将引用别名。 - 对于
t1
中的每一行,查找t2
中将t1
行标识为其父行的所有记录 - 如果
t1
行没有子行,t2.category_id
将为空 - 我们只想筛选
t1
没有子项的行
我认为如果您重命名您的 table 别名会更容易看到发生了什么:
SELECT tparent.name
FROM category AS tparent
LEFT JOIN category as tchild
ON tparent.category_id = tchild.parent
WHERE tchild.category_id IS NULL;
现在可能更容易看出您要的是没有子项的所有父类别名称的列表 [tchild.category_id IS NULL]