在数据库中,有一个名为category的表:
CREATE TABLE category(
category_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
parent INT DEFAULT NULL
);
它是为了制作相邻列表模型树而创建的。以下是目前表格中的内容:
在这个例子中(你可以在底部找到源链接),下面的sql代码用于获取表中的“leaf”元素,“leaf”元素是表中没有的行任何其他行在“父”列中使用其“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代码的结果给出了这个结果:
例如,表中没有行在父列中具有值3,因此TUBE(with category_id == 3)是“leaf”元素。
问题:为什么这个sql代码在逻辑上给出了这个结果?我很高兴它确实存在,因为它是我所需要的,但我不能完全围绕它背后的推理。
示例来源:http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
答案 0 :(得分:2)
每当你看到这种模式时:
SELECT ...
FROM TableA
LEFT JOIN TableB ON TableA.column = TableB.column
WHERE TableB.id is null
思考:"在TableA中查找TableB中不存在的行。
您的查询意味着找到没有孩子的类别"。如果删除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
表开始,将其别名为t1
和t2
。我将从现在开始引用别名。t1
中的每一行,查找t2
中标识t1
行为其父t1
行没有孩子,t2.category_id
将为空t1
行答案 1 :(得分:0)
我认为如果重命名表别名,将会更容易看到发生了什么:
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]