簡體   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