繁体   English   中英

在 MySQL 中按别名选择列

[英]Select column by alias in MySQL

我想了解 MySQL 中的某些特定行为。 运行“select @@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 版本中。 唯一的例外是当涉及包含聚合函数的列时(如下所示)——它会抛出 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 行为的更具体和更好的书面问题,可以在这里找到。

简短的回答:

  1. 对 SELECT 列表中的别名的引用或
  2. 别名表达式

到目前为止,我在这方面找到的唯一文档是: https : //bugs.mysql.com/bug.php?id=79549

在该链接中有以下内容:

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

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

鉴于此:创建表 t1(a int, b int),

SELECT 列表中的别名无效:

  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”(项目列表中的前向引用)

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

我还在寻找标准文档中描述此功能的错误报告之外的文档; 但到目前为止还没有运气。

为什么不再次使用相同的表达式,它不会像Reuse一样伤害Reuse

SELECT 
    CONCAT(a, b) AS 'c1', CONCAT(CONCAT(a, b), 2)
FROM
    (SELECT 'a', 'b', 'c' UNION ALL SELECT 1, 2, 3) t1;
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;

或者更好,如果您有窗口函数(不是在您的 MySQL 版本上,而是在读者上):

// only with MariaDB 10.2 and up

WITH q AS (SELECT 'a' a, 'b' b, 'c' c UNION ALL SELECT 1, 2, 3) 
    SELECT * FROM q WHERE  a='a'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM