别名是什么
别名用 AS 给输出列或表起一个短名字,AS 可以省略但显式写更清楚。列别名只影响结果集的列名,不改变表结构,也不会写回数据库;表别名主要用在连接查询里缩短引用,并让自连接能区分同一张表的两个角色。别名的作用范围与逻辑求值顺序一致:WHERE 看不到列别名,ORDER BY 与 HAVING 可以看到。
基本信息
| 列别名 | SELECT price * qty AS amount |
|---|---|
| 表别名 | FROM order_items AS oi |
| 省略 AS | SELECT id name 合法但可读性差,不推荐 |
| 含空格或中划线 | MySQL 用反引号,PostgreSQL 用双引号 |
| 大小写 | PostgreSQL 双引号内的名字区分大小写 |
| 作用域 | 列别名可用于 ORDER BY / HAVING,不能用于 WHERE |
典型使用场景
- 给计算列起业务名:price * qty AS amount,让接口字段自解释
- 消除同名列歧义:连接查询里用表别名限定 user_id 属于哪张表
- 自连接区分角色:FROM employees AS e JOIN employees AS m ON e.manager_id = m.id
- 兼容历史字段名:SELECT new_col AS old_name,老代码无需改动
- 缩短长表名:数据仓库里把 ods_order_detail_202401 AS d
示例
示例
SELECT u.id,
u.name AS user_name, # 输出列改名
o.amount AS order_amount, # 原列也可以起别名
o.amount * 1.06 AS gross # 计算列起别名
FROM users AS u # 表别名
JOIN orders AS o ON o.user_id = u.id
ORDER BY gross DESC; # ORDER BY 可以用列别名带空格特殊字符的别名
带空格特殊字符的别名
-- MySQL:反引号
SELECT 1 AS `total count`;
SELECT 1 AS `order-total`;
-- PostgreSQL:双引号
SELECT 1 AS "total count";
SELECT 1 AS "order-total";别名可用位置
| 位置 | 列别名 | 说明 |
|---|---|---|
| SELECT 清单 | 定义处 | 不算使用,是别名的诞生点 |
| WHERE | 不可用 | 求值早于 SELECT,MySQL 报 Unknown column |
| GROUP BY | 一般不可用 | 多数版本按原表达式解析,别依赖 |
| HAVING | 可用 | 求值晚于 SELECT |
| ORDER BY | 可用 | 求值晚于 SELECT,最常用 |
| 子查询外层 | 不可用 | 外层只能看到子查询的输出列名 |
PostgreSQL 里双引号保留大小写:AS "Total" 与不加引号的 total 是两个不同的名字,从 MySQL 迁过来的 SQL 容易在这里踩坑。
MySQL 允许单引号写别名(AS 'x'),属非标准用法;跨库复用的 SQL 统一写反引号或双引号形式。
别名不能用在 WHERE 里:SELECT price*qty AS amount FROM t WHERE amount > 100 会报未知列,改写为 WHERE price*qty > 100,或把计算包进子查询再在外层过滤。
需要按别名再过滤时套一层:SELECT * FROM (SELECT price*qty AS amount FROM t) x WHERE x.amount > 100,内层别名成为外层的真实列名,这是最通用的绕行方式。