mysql 为什么在SQL查询中这里需要点符号?

63lcw9qa  于 2023-01-29  发布在  Mysql
关注(0)|答案(3)|浏览(146)

您将看到一个表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),它仍然给我错误的答案。为什么会这样呢?
我对.(点)的用法感到困惑

flvlnr44

flvlnr441#

您在查询中使用了两次BST.告诉DBMS您正在使用哪个示例。如果省略,DBMS必须隐式选择它。
隐式选择的表在整个查询中并不相同。
使用更显式的别名时,您的查询为:

SELECT N,
CASE
   WHEN P IS NULL THEN 'Root'
   WHEN (SELECT COUNT(*) FROM BST InsideAlias WHERE OutsideAlias.N=InsideAlias.P)>0 THEN 'Inner'
   ELSE 'Leaf'
END AS PLACE
FROM BST OutsideAlias

删除别名时,隐式选择的BST示例为:

  • 在子查询SELECT COUNT(*) FROM BST InsideAlias中:InsideAlias
  • 在查询的其余部分中:OutsideAliasInsideAlias无论如何都超出了查询其余部分的范围)。

这意味着:

(SELECT COUNT(*) FROM BST InsideAlias WHERE N=P)

相当于

(SELECT COUNT(*) FROM BST InsideAlias WHERE InsideAlias.N=InsideAlias.P)

因此,您得到的结果是错误的,因为COUNT(*)需要一个节点作为自己的父节点才能大于0。
相反,OutsideAlias.N=InsideAlias.P转换为:我的节点是其他节点的父节点吗?另一种测试方法是使用EXISTS (SELECT * FROM BST WHERE OutsideAlias.N = P),尽管这不是您的问题。

zwghvu4y

zwghvu4y2#

这是关于相关子查询的。相关子查询是一个子查询,它包含了一个表的引用,这个表也出现在外部查询中。我们如何区分子查询表和外部查询中的表呢?有两种情况。
1.内部表和外部表是不同的表(具有不同的名称):在这种情况下,我们只使用它们的表名,因为它们是不同的。
1.内表和外表是同一个表(表名相同):在这种情况下,为了区分它们,我们需要给予外部表一个别名(如果你给内部表一个别名,例如g i,并使用i.n=n,if意味着innertable.n=innertable.n,而不是innertable.n=outertable.n)
因此,要回答您的第一个问题,请检查查询旁边的注解:

SELECT N,
CASE
   WHEN P IS NULL THEN 'Root'
   WHEN (SELECT COUNT(*) FROM BST -- this is the table name of the subquery table which does not need an alias
        WHERE B.N=P /*B.N=P means table condition of this subquery requires that value of P from this subquery table BST equals to column p of its outer(parent) table which is aliased as B */)>0 THEN 'Inner'
   ELSE 'Leaf'
END AS PLACE
FROM BST B -- this is the table name of the main query which needs an alias so it can be distinguishable in the correlated subquery  
ORDER BY N;

在回答您的第二个问题之前,我们如何区分两个同名的表呢?我们需要给其中一个表取不同的名称,这就需要使用别名。但是如果您使用BST.N = P(在第二个问题中,您没有说明将条件放在何处。根据上下文,我假设您指的是子查询表条件)在子查询中,则此BST实际上表示innertable,从而使表达式BST.N = PN=P相同(两者都使用innertable作为前缀)。要解决此问题,请为outer表提供别名,并将该别名用作子查询中使用的outer表列的前缀。

ar7v8xwq

ar7v8xwq3#

它与名称空间有关--列和表达式“存在”的地方。
SQL查询可以包括多个命名空间,其中列和表达式被命名并且可以被访问。
在查询中有两个名称空间:

  • 一个用于主查询。
  • 另一个用于内部标量子查询。

在第一个查询中,可以通过预先添加名称空间B来 * 引用 * 主查询中的列,如B.<column>中所示,而可以使用名称空间BST来引用内部名称空间中的列,如BST.<column>中所示。
如果列名(或表达式名)没有显式包含名称空间,则最接近的名称空间优先。
在第二个查询中,您没有指定命名空间,因此表达式N = P中的列NP引用同一个内部表,因此子查询与主查询“不相关”。在第一个查询中,B.N引用主查询中的列,因此表达式B.N = P比较来自不同表的列。然后查询被“相关”。

相关问题