1. 列别名(Column Alias)速查表

SQL 子句 能否定义列别名? 能否使用列别名? 说明
SELECT ✅ 能 ✅ 能 唯一拥有定义列别名权限的子句
WHERE ❌ 不能 ❌ 不能 执行在 SELECT 之前,别名尚未生成
GROUP BY ❌ 不能 ❌ 不能 执行在 SELECT 之前
HAVING ❌ 不能 ✅ 能 (SQLite支持) 仅能使用 SELECT 中已定义的别名
ORDER BY ❌ 不能 ✅ 能 执行在 SELECT 之后,可直接使用别名

2. 表别名(Table Alias)速查表

定义位置 语法示例 说明
FROM 子句 FROM Orders AS o 最常见的定义位置
JOIN 子句 JOIN Customers AS c ON ... 多表连接时简化表名
子查询(派生表) FROM (SELECT ...) AS t 必须定义别名,否则报错
CTE(WITH 语句) WITH my_table AS (...) CTE 名称即为表别名
UPDATE 语句 UPDATE Orders AS o SET ... ⚠️ SQLite 中通常省略 AS,直接写 Orders o
DELETE 语句 DELETE FROM Orders AS o WHERE ... 简化多表关联删除

3. SQL 逻辑执行顺序与别名权限

数据库实际执行的顺序如下:

  1. FROM / JOIN:加载表,可定义表别名
  2. WHERE:过滤原始行(❌ 不能用列别名)
  3. GROUP BY:数据分组
  4. HAVING:过滤分组结果(✅ 可用列别名)
  5. SELECT:提取列,定义列别名
  6. ORDER BY:排序(✅ 可用列别名)

4. 常见避坑指南

  • 雷区 1:在 WHERE 中使用列别名(如 WHERE total > 100),会报 Unknown column 错误。
  • 雷区 2:在 HAVING 中定义别名(如 HAVING COUNT(*) AS cnt > 10),语法错误。
  • 雷区 3:定义了表别名后,在查询中混用原表名(如 FROM Orders AS o WHERE Orders.id = 1),会报错。
  • 雷区 4:子查询作为派生表时忘记起别名,如 FROM (SELECT ...),必须加上 AS t。

5. 核心口诀

  • 列别名:SELECT 定,HAVING / ORDER BY 用,WHERE 绝对碰不得。
  • 表别名:FROM / JOIN / 子查询 / CTE 都能定,一旦定了原表名就作废。