您将看到一个表BST,其中包含两列:N和P,其中N表示二叉树中某个节点的值,P是N的父节点。
问题-编写一个查询,查找按节点值排序的二叉树节点类型。为每个节点输出以下内容之一:
Root: If node is root node.
Leaf: If node is leaf node.
Inner: If node is neither root nor leaf node.
解决方案1 -我对别名B使用点(.)表示法。N=P
SELECT N,
CASE
WHEN P IS NULL THEN 'Root'
WHEN (SELECT COUNT(*) FROM BST WHERE B.N=P)>0 THEN 'Inner'
ELSE 'Leaf'
END AS PLACE
FROM BST B
ORDER BY N;
解决方案2 -不使用和点运算符?
SELECT N,
CASE
WHEN P IS NULL THEN 'Root'
WHEN (SELECT COUNT(*) FROM BST WHERE N=P)>0 THEN 'Inner'
ELSE 'Leaf'
END AS PLACE
FROM BST
ORDER BY N;
我的问题是-
1.为什么解答1会产生正确答案,是因为.(点)吗?如果是因为点运算符,为什么我们不对P(B.N = P)使用点运算?
1.即使我修改了解2,写成(BST.N = P),它仍然给我错误的答案。为什么会这样呢?
我对.(点)的用法感到困惑
3条答案
按热度按时间flvlnr441#
您在查询中使用了两次
BST
。.
告诉DBMS您正在使用哪个示例。如果省略,DBMS必须隐式选择它。隐式选择的表在整个查询中并不相同。
使用更显式的别名时,您的查询为:
删除别名时,隐式选择的BST示例为:
SELECT COUNT(*) FROM BST InsideAlias
中:InsideAlias
OutsideAlias
(InsideAlias
无论如何都超出了查询其余部分的范围)。这意味着:
相当于
因此,您得到的结果是错误的,因为
COUNT(*)
需要一个节点作为自己的父节点才能大于0。相反,
OutsideAlias.N=InsideAlias.P
转换为:我的节点是其他节点的父节点吗?另一种测试方法是使用EXISTS (SELECT * FROM BST WHERE OutsideAlias.N = P)
,尽管这不是您的问题。zwghvu4y2#
这是关于相关子查询的。相关子查询是一个子查询,它包含了一个表的引用,这个表也出现在外部查询中。我们如何区分子查询表和外部查询中的表呢?有两种情况。
1.内部表和外部表是不同的表(具有不同的名称):在这种情况下,我们只使用它们的表名,因为它们是不同的。
1.内表和外表是同一个表(表名相同):在这种情况下,为了区分它们,我们需要给予外部表一个别名(如果你给内部表一个别名,例如g i,并使用i.n=n,if意味着innertable.n=innertable.n,而不是innertable.n=outertable.n)
因此,要回答您的第一个问题,请检查查询旁边的注解:
在回答您的第二个问题之前,我们如何区分两个同名的表呢?我们需要给其中一个表取不同的名称,这就需要使用别名。但是如果您使用
BST.N = P
(在第二个问题中,您没有说明将条件放在何处。根据上下文,我假设您指的是子查询表条件)在子查询中,则此BST实际上表示innertable,从而使表达式BST.N = P
与N=P
相同(两者都使用innertable作为前缀)。要解决此问题,请为outer表提供别名,并将该别名用作子查询中使用的outer表列的前缀。ar7v8xwq3#
它与名称空间有关--列和表达式“存在”的地方。
SQL查询可以包括多个命名空间,其中列和表达式被命名并且可以被访问。
在查询中有两个名称空间:
在第一个查询中,可以通过预先添加名称空间
B
来 * 引用 * 主查询中的列,如B.<column>
中所示,而可以使用名称空间BST
来引用内部名称空间中的列,如BST.<column>
中所示。如果列名(或表达式名)没有显式包含名称空间,则最接近的名称空间优先。
在第二个查询中,您没有指定命名空间,因此表达式
N = P
中的列N
和P
引用同一个内部表,因此子查询与主查询“不相关”。在第一个查询中,B.N
引用主查询中的列,因此表达式B.N = P
比较来自不同表的列。然后查询被“相关”。