Mysql 请解释一下这个问题好吗?

Mysql 请解释一下这个问题好吗?,mysql,sql,subquery,case,correlated-subquery,Mysql,Sql,Subquery,Case,Correlated Subquery,我有一个表,其中n是节点,p是节点的父节点。我需要找到哪一个是父对象、内部对象和叶对象。如果P为NULL,则父对象是所有P的父对象。内部是至少一片叶子的父代,而叶子什么都没有 n | p | +------+------+ | 1 | 2 | | 3 | 2 | | 6 | 8 | | 9 | 8 | | 2 | 5 | | 8 | 5 | | 5 | NULL | +------+------+ 上

我有一个表,其中n是节点,p是节点的父节点。我需要找到哪一个是父对象、内部对象和叶对象。如果P为NULL,则父对象是所有P的父对象。内部是至少一片叶子的父代,而叶子什么都没有

 n    | p    |
+------+------+
|    1 |    2 |
|    3 |    2 |
|    6 |    8 |
|    9 |    8 |
|    2 |    5 |
|    8 |    5 |
|    5 | NULL |
+------+------+ 
上表列出了该表。我不明白这个查询是如何工作的

SELECT N, IF(P IS NULL,'Root',IF((SELECT COUNT(*) FROM BST WHERE P=B.N)>0,'Inner','Leaf')) FROM BST AS B ORDER BY N;
这里我无法理解的部分是p=B.N。当我单独执行这个查询时,它显示count为零,但当我执行整个查询时,答案是正确的。请以上表中的值为例说明此查询是如何工作的。提前谢谢

这个问题的答案是

 N    | asnwer |
+------+--------+
|    1 | Leaf   |
|    2 | Inner  |
|    3 | Leaf   |
|    5 | Root   |
|    6 | Leaf   |
|    8 | Inner  |
|    9 | Leaf   |
+------+--------+

在上面的查询中,p=B.N没有例如的值,p的第一个值是2,N的第一个值是1。两者不相等,在整个表格中,P的值不等于N。那么结果集的正确性如何。请解释我更喜欢
大小写
表达式而不是函数
IF()

我将条件更改为先检查为
=
,而不是

对于相关子查询中的表,我还使用了别名
BB
,只是想知道这不是原始查询表,而是表的另一个副本。

对于表格的每一行,如果列
p
null

如果它是
null
,那么结果当然是
“Root”

如果它不是
null
,则必须检查表中
N
列的值(这是
B.N
表示的值)等于
p
列的行数(这是
BB.p
表示的值)。

为了得到这个结果,需要另一份进行计数的表格副本。
如果结果等于
0
,这意味着表中没有任何行作为父行
N
B.N
),因此结果是
'Leaf'


在任何其他情况下,结果是
'internal'

我将使用带有
exists的
case
表达式:

select b.*,
       (case when b.p is null then 'parent'
             when exists (select 1 from bst b2 where b2.p = b.n) then 'inner'
             else 'leaf'
        end) as node_type
from bst b;
exists
只是检查是否存在其父节点为该节点的另一个节点。
其中
子句是一个关联子句。您将注意到,在此版本中,所有列都使用表别名限定,所以很清楚哪些列引用哪些表


在这种情况下,
exists
count()
更有效,因为
exists
可以在第一个匹配值处停止。

您熟悉“相关子查询”的概念吗?我知道相关子查询的含义。你能解释一下吗,因为我不知道它是怎么工作的。刚才看到了查询的结构
select b.*,
       (case when b.p is null then 'parent'
             when exists (select 1 from bst b2 where b2.p = b.n) then 'inner'
             else 'leaf'
        end) as node_type
from bst b;