当前位置: 首页 > 面试题库 >

为什么通常无法重用别名的mySQL为什么能够解析这些列别名?

闻人越
2023-03-14
问题内容

大多数SQL专家会说,不能在同一级别的select中重用别名;通常要解决此问题,使用CTE;或者将查询包装为子查询,以便可以引用别名。但是,如果在select自身的子查询中引用了别名,则mySQL似乎允许这种情况。因此,从技术上讲,它不在同一水平上。

演示:

SELECT CONCAT(a, b) AS c1, CONCAT((SELECT c1), 2)
FROM (SELECT 'a' a, 'b' b, 'c' c UNION ALL 
      SELECT '1', '2', '3') t1;

SELECT 1 a, 2 b, (SELECT A+B) c
     , concat((SELECT a),(SELECT b)) d 
     , greatest((SELECT a),(SELECT b), (SELECT c))

以上两个查询均有效。他们工作。(或在使其看起来像工作时做得非常好)

尽管事实并非如此:正如人们所期望的那样。

SELECT CONCAT(a, b) AS c1, CONCAT(c1, 2)
FROM (SELECT 'a' a, 'b' b, 'c' c UNION ALL 
      SELECT '1', '2', '3') t1;

因此,这里的问题有两个:

这是缺少文档的mySQL“功能”还是有人可以解释编译器如何解析别名?

这是一个可以依靠的有文档记录的功能吗?如果是,则在哪里记录此文件,以便人们可以理解使用此html" target="_blank">方法的含义?


问题答案:

在我看来,这似乎是一个解析错误(在其他数据库中,前两个查询会出现错误)。

我可以猜测发生了什么。MySQL正在解析子查询(selectc1)。它c1在子查询中找不到,因此它开始在外部查询中查找引用。

根据SQL的规则,它只能查看from子句中的列。但是,MySQL似乎也在寻找列别名。

尽管我将其称为错误,但MySQL似乎将其视为一项功能。(还有另一个将“错误”视为“功能”的MySQL示例。)考虑以下查询:

SELECT CONCAT((SELECT c1), 2), CONCAT(a, b) AS c1
FROM (SELECT 'a' a, 'b' b, 'c' c UNION ALL 
      SELECT '1', '2', '3') t1;

并产生错误:

不支持参考“ c1”(项目列表中的前向参考)

该错误表明MySQL故意解析“向后”引用。

出于记录,我永远不会依赖此功能。它不仅违反了ANSI标准,而且在数据库中具有独特的行为。令人困惑。考虑一下这个小修改:

SELECT CONCAT(a, b) AS c1, CONCAT((SELECT c1), 2)
FROM (SELECT 'a' a, 'b' b, 'c' c UNION ALL 
      SELECT '1', '2', '3') t1 CROSS JOIN
     (SELECT 'abcdef' as c1) x;

这c1的确查询决心?我让你知道。而且这甚至没有考虑到c1可能是一个变量。



 类似资料:
  • 有25种类型的空白。在下面的代码中显示,25种类型中有4种在Java中不被视为空白。为什么? 参考-https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/character.html#IsWhitespace(char)

  • 问题内容: 我尝试使用MySQL: 我得到这个: 注意: 此查询是自动生成的,条件基于表别名。 为什么会出现此错误? 有什么方法可以在where子句中使用表别名? 这是MySQL特有的吗? 问题答案: 您可以这样使用SQL:

  • 问题内容: 我只是想知道为什么我们通常在两个布尔之间使用逻辑 而不是按位,尽管它们都运行良好。 我的意思是,请看以下内容: | | 我们可以|代替使用||吗?与&和相同&&。 问题答案: 如果使用和形式,而不是这些运算符的和形式,则Java不会费心地单独评估右手操作数。 多数情况下,是否要缩短评估是一个问题。 说明短路好处的一个好方法是考虑以下示例。 正如Jeremy和Peter提到的,短路的另一

  • 类无法解析,为什么?这就引出了一个问题:在哪里可以找到的javadoc? null

  • 问题内容: 抱歉,如果这是重复的,但是我还没有找到。为什么我不能用在我的定义列别名从当我使用 ? 考虑以下简单查询: 结果是一个错误: 无效的列名“ NewValue” 这是一个sql小提琴。(替换用的是麓的注释掉) 我知道我可以使用像 这里 在这种情况下,但实际上在查询比较复杂,我想保持它尽可能地易读。我是否必须改用子查询或CTE,如果是这样,为什么呢? *由于Mikael Eriksson注释

  • 问题内容: URL u =新URL(“ telnet://route-server.exodus.net”); 这行正在生成: java.net.MalformedURLException:未知协议:telnet 而且我遇到其他以“ news://”开头的URL的类似问题 这些是从ODP提取的URL,所以我不明白为什么会出现此类异常。 问题答案: 问题 Java 之所以抛出a,是因为它找不到该协议