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

xQbert

大多数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;

因此,这里有两个问题:

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

  2. 这是一个可以依靠的文档功能吗?如果是,则在哪里记录此文件,以便您可以理解使用此方法的含义?

这个问题源于已经问过的一个问题:在MySQL中按别名选择列

戈登·利诺夫

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

我可以猜测发生了什么。MySQL正在解析子查询(select c1)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可能是一个变量。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章