0Pricing
Coding Interview Prep · 课时

列投影与别名陷阱

了解为什么不能在 WHERE 中引用 SELECT 别名,以及面试官如何考查别名的作用域

列投影与别名陷阱 是 CoddyKit 上的免费 Coding Interview Prep 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Coding Interview Prep 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Coding Interview Prep 课程共包含 4 节课。

投影:选择列

选择查询要返回哪些列,称为投影——每次书写 SELECT 时,您都在进行投影。在实际代码中请明确列出所需列;SELECT * 只用于快速探索。

SELECT id, first_name, email
FROM employees;

为什么面试官不喜欢 SELECT *

为什么面试官不喜欢在应用代码中使用 SELECT *?因为它很脆弱(列的顺序可能变化)、浪费带宽、影响索引的使用,还会隐藏您实际需要的内容。请明确写出列名。👍

使用 AS 为列设置别名

别名会为输出中的列重新命名。请使用 AS 来提高可读性——对于计算列尤其有效,可以为 salary * 12 这样的复杂表达式提供简洁易读的列标题。

SELECT first_name AS name,
       salary * 12 AS annual_salary
FROM employees;

为带空格的别名加引号

如果别名包含空格或保留字,就必须为它加引号。可移植且符合标准的方式是使用双引号。提示:请直接使用下划线命名法的名称,这样可以完全避免加引号。

SELECT salary AS "Annual Pay"
FROM employees;

最大的陷阱:WHERE 中的别名作用域

这是最常考的陷阱:在 SELECT 中定义别名,然后在 WHERE 中使用它进行筛选,但操作会失败。WHERE 在 SELECT 之前执行,因此该别名尚不存在。

-- This raises an error
SELECT salary * 12 AS annual_salary
FROM employees
WHERE annual_salary > 100000;

原因:逻辑执行顺序

解决方法是掌握逻辑子句顺序:FROM、WHERE、GROUP BY、HAVING、SELECT,然后是 ORDER BY。SELECT 接近执行末尾,因此前面的子句无法看到它定义的别名。

修复方法 1:重复表达式

最具可移植性的修复方法很简单:在 WHERE 中直接重复表达式,不要使用别名。虽然会稍显冗长,但它在每种数据库中都始终有效。

SELECT salary * 12 AS annual_salary
FROM employees
WHERE salary * 12 > 100000;

修复方法 2:包装在子查询或 CTE 中

如果重复很长的表达式看起来不够简洁,可以先在子查询或 CTE 中计算它。这样,别名就会成为一个真正的列,外层 WHERE 便可以根据它进行筛选。

SELECT *
FROM (
  SELECT first_name, salary * 12 AS annual_salary
  FROM employees
) t
WHERE annual_salary > 100000;

允许使用别名的位置:ORDER BY

好消息是:ORDER BY 可以使用 SELECT 别名,因为它在 SELECT 之后执行。因此,WHERE、GROUP BY 和 HAVING 看不到别名,但 ORDER BY 可以。

SELECT first_name, salary * 12 AS annual_salary
FROM employees
ORDER BY annual_salary DESC;

值得顺带提及的方言差异

有一点值得顺带提及:MySQL 对在 GROUP BY 和 HAVING 中使用别名的限制较为宽松,而 Postgres 和 SQL Server 遵循标准。先根据逻辑顺序推理,再说明这个例外。

表别名与列别名

不要混淆它们。表别名会缩短表名,并且在任何位置都可见,甚至在 WHERE 中也可以。列别名则会重命名输出结果,不能在这些位置使用——两者恰好相反。

SELECT e.first_name, e.salary AS pay
FROM employees AS e
WHERE e.salary > 50000;

快速检查

测试这一核心陷阱。

回顾

回顾:优先选择明确列名,而不是 SELECT *,并使用 AS 创建别名。SELECT 别名在 WHERE/GROUP BY/HAVING 中不可见,但可以在 ORDER BY 中使用。可以通过重复表达式或使用 CTE 来修复。

常见问题解答

「列投影与别名陷阱」课时是免费的吗?

是的 — 「列投影与别名陷阱」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Coding Interview Prep 课程的其余内容,请升级到 CoddyKit PRO。 Coding Interview Prep 课程共包含 4 节课。

「列投影与别名陷阱」这节课中我会学到什么?

了解为什么不能在 WHERE 中引用 SELECT 别名,以及面试官如何考查别名的作用域 你通过在浏览器中直接运行的动手代码来练习 Coding Interview Prep,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Coding Interview Prep 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Coding Interview Prep 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「列投影与别名陷阱」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Coding Interview Prep 课中编写并运行代码吗?

能。每节 Coding Interview Prep 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 列投影与别名陷阱
  2. 计算列与表达式优先级
  3. DISTINCT 与 GROUP BY 的去重比较
  4. SELECT 中的 CASE 表达式
← 返回 Coding Interview Prep