在MySQL中按别名选择列

在MySQL中按别名选择列,mysql,sql,database,Mysql,Sql,Database,我想了解MySQL中的某些特定行为。运行“选择@@version”,我看到我的版本是5.6.34-log 让我使用生成的表来放置示例,以便更容易复制: SELECT CONCAT(a, b) AS 'c1', CONCAT((SELECT c1), 2) FROM (SELECT 'a', 'b', 'c' UNION ALL SELECT 1, 2, 3) t1; 正如标题所示,我最初搜索的是如何通过别名选择列,以便重用计算字段,避免长时间查询。大多数答案要么建议使用子查询

我想了解MySQL中的某些特定行为。运行“选择@@version”,我看到我的版本是5.6.34-log

让我使用生成的表来放置示例,以便更容易复制:

SELECT 
    CONCAT(a, b) AS 'c1', CONCAT((SELECT c1), 2)
FROM
    (SELECT 'a', 'b', 'c' UNION ALL SELECT 1, 2, 3) t1;
正如标题所示,我最初搜索的是如何通过别名选择列,以便重用计算字段,避免长时间查询。大多数答案要么建议使用子查询,要么建议使用变量——一个可读性差,而另一个无法由自己的DB开发人员保证,如中所述。然后,我从中学习了这个方法,并不能完全理解它——事实上,我甚至不知道如何调用这种操作/子句

它似乎工作得很好,至少在这个MySQL版本中是如此。唯一的例外是当它涉及到包含聚合函数的列时(如下所示)——它抛出了1247(错误引用)错误,这感觉非常合理

-- THIS DOESN'T WORK!
SELECT 
    CONCAT(a, b) AS c1, CONCAT((SELECT c1), 2) as c2
FROM
    (SELECT 'a' as a, 'b' as b, 'c' as c UNION ALL SELECT '1', 2, 3) t1;
我已经阅读了很多关于这个主题的答案,但这是对这种操作的唯一参考,而且,由于我不知道它的名称,我无法深入研究它。有人知道这个结构叫什么吗?我怎样才能更好地理解它

编辑:我没有尝试执行“不工作”查询中显示的操作。事实上,我正试图理解MySQL的行为。已经存在的问题是如何理解如何使用子查询,等等-这不是重点。我的主要问题是理解MySQL在那里执行什么样的操作,以及它是如何调用的,因为我从来没有读过类似的东西(这是一个带有自动选择的查询吗?)


编辑2:这篇文章提出了一个关于MySQL行为的更具体、更好的问题,可以找到。

为什么不再次使用同一个表达式,它不会对重用造成太大的伤害

SELECT 
    CONCAT(a, b) AS 'c1', CONCAT(CONCAT(a, b), 2)
FROM
    (SELECT 'a', 'b', 'c' UNION ALL SELECT 1, 2, 3) t1;
或者更好,如果您有窗口功能(不是在您的MySQL版本上,而是针对读者):

简短答复:

  • 对“选择”列表或中别名的引用
  • 别名表达式
  • 到目前为止,我在这方面找到的唯一文档是:

    在该链接中有以下内容:

    [2015年12月9日15:35]Roy Lyseng ... 以下是原始决定的较长背景:

    与WHERE子句(以及GROUP BY)中的子查询中对别名的引用相反,没有理由(标准符合性除外)不允许在SELECT列表中引用别名,因为它们应该在查询执行的同一阶段可用。但是5.6中的支持非常随意:

    考虑到这一点:创建表t1(a int,b int)

    选择列表中的别名无效:

      select a+b as c,c+1 from t1;
    
    错误1054(42S22):“字段列表”中的未知列“c”

    但在子查询中,对c的引用是有效的:

      select a+b as c,(select c+1) from t1;
    
    子查询必须在别名定义之后:

      select (select c+1),a+b as c from t1;
    
    错误1247(42S22):不支持引用“c”(项目列表中的正向引用)

    因此,很容易说,对选择列表中别名的引用的支持是相当临时的。尽管如此,我们仍将尝试重新实现旧的解决方案,但不会试图清理此功能支持中的明显漏洞。但是在WHERE子句中引用子查询中的别名将不会被重新实现


    我还在寻找标准文档中描述此功能的bug报告之外的文档;但到目前为止还不走运。

    改用派生表。@jarlh,Op已经说过了。。。不满意子查询您不能在同一查询级别引用别名。所以你必须重复代码,使用子查询,或者做一个悲伤的人。@Rahul,高兴还是不高兴-没有给出任何理由。。。OP已经有子查询,这里可能需要另一个子查询。如果您可以升级到MariaDB的最新版本(10.2),您可以使用窗口功能,这样您就可以在多个级别上重复使用同一查询。您还可以执行
    CONCAT(a,b,2)
    ;)@JuanCarlosOropeza,是的,你可以…:)好。。。这里我的表达式很简单,这是一个示例。当我开始使用嵌套的IFs、CASE等时,很难理解它是什么happening@LucasLima,则子查询/view/CTE(MySQL中不支持CTE)是option@Rahul,我明白了。只是编辑了这个问题,让它更清楚。我知道怎么做。我想理解为什么我不应该使用我在问题中展示的结构,因为它更干净,也更有效。OP发布的SQL代码也有效。这里是fiddle Goin来编辑问题以符合您的提示,并使我的观点更清楚。@Rahul odd如果我在rexTester上尝试同样的方法,它会返回服务不可用;但是如果我尝试上面的方法,它会起作用。现在我知道这不是问题,但奇怪的行为是不同的。
      select a+b as c,(select c+1) from t1;
    
      select (select c+1),a+b as c from t1;