-- 错误写法:直接求和会重复累加 SELECT SUM(freight * coefficient) FROM order_details; -- 正确写法:先去重,再计算 SELECT SUM(freight * coefficient) AS 去重后总额 FROM ( SELECT DISTINCT order_id, freight, coefficient FROM order_details ) t;
你这里最后的t是个啥
SQL 别名 t 的详细讲解
您问的这个问题非常关键!t 是子查询的别名(也叫派生表别名),让我详细解释。
一、t 是什么?
sql
FROM ( SELECT DISTINCT order_id, freight, coefficient FROM order_details) t
t 是子查询的别名,相当于给这个子查询的结果集起了一个临时名字,叫 t。
二、为什么需要别名?
在 SQL 中,任何子查询都必须有一个别名。如果没有别名,会报错!
sql
-- ❌ 错误写法:子查询没有别名SELECT * FROM ( SELECT DISTINCT order_id, freight FROM order_details);-- ✅ 正确写法:子查询必须有别名SELECT * FROM ( SELECT DISTINCT order_id, freight FROM order_details) t;
三、词源角度
| 符号 | 含义 |
|---|---|
t | Table(表)的缩写,表示这是一个临时表 |
| 别名 | 给表或子查询起的临时名字 |
命名惯例:
t= table(表)s= subquery(子查询)a、b、c= 临时表别名t1、t2= 多个临时表时用数字区分
四、别名可以改成什么名字?
可以改成任何合法的名称!
sql
-- 以下写法都正确FROM (...) t -- 单字母FROM (...) tmp -- 缩写FROM (...) sub -- 子查询的缩写FROM (...) my_table -- 描述性名称FROM (...) a -- 字母aFROM (...) 我的表 -- 中文(不推荐)
五、别名的作用
1、引用子查询中的列
sql
SELECT t.order_id, t.freightFROM ( SELECT DISTINCT order_id, freight FROM order_details) t;
2、多表连接时区分来源
sql
SELECT a.order_id, b.order_idFROM order_table aJOIN other_table b ON a.id = b.id;
3、自连接(同一张表连接两次)
sql
SELECT a.name, b.nameFROM employees aJOIN employees b ON a.manager_id = b.id;
六、可视化理解
text
┌─────────────────────────────────────────────────────────────┐ │ 子查询结果集(没有名字) │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ order_id │ freight │ coefficient │ │ │ │ │ ORD001 │ 10 │ 1.2 │ │ │ │ │ ORD002 │ 20 │ 1.5 │ │ │ │ │ ORD003 │ 15 │ 1.0 │ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ │ 起别名 t │ │ ↓ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 表 t(临时名称) │ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ │ │ order_id │ freight │ coefficient │ │ │ │ │ │ │ ORD001 │ 10 │ 1.2 │ │ │ │ │ │ │ ORD002 │ 20 │ 1.5 │ │ │ │ │ │ │ ORD003 │ 15 │ 1.0 │ │ │ │ │ │ └─────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘
七、完整代码解读
sql
SELECT SUM(freight * coefficient) AS 去重后总额FROM ( SELECT DISTINCT order_id, freight, coefficient FROM order_details) t;
| 代码部分 | 含义 |
|---|---|
SELECT SUM(freight * coefficient) | 对 t 表中的 freight * coefficient 求和 |
FROM (...) t | t 是括号内子查询的别名 |
子查询 | 先去重得到临时结果集 |
t | 给这个临时结果集起名叫 t,让外层查询可以引用它 |
八、常见别名命名习惯
| 别名 | 含义 | 使用场景 |
|---|---|---|
t | table | 单个临时表 |
a、b、c | alias | 多个表或子查询 |
t1、t2 | table1, table2 | 多个临时表 |
sub | subquery | 子查询 |
derived | derived table | 派生表 |
tmp | temporary | 临时结果 |
九、总结
| 问题 | 答案 |
|---|---|
t 是什么? | 子查询的别名(临时表名) |
| 为什么需要别名? | SQL 语法要求,子查询必须有一个名字 |
| 可以改成别的名字吗? | ✅ 可以,任何合法名称都可以 |
| 别名有什么作用? | 让外层查询可以引用子查询的列 |
| 不写别名会怎样? | 报语法错误 |
一句话总结:t 是子查询的别名,就像给人起外号一样——子查询本身没有名字,我们需要给它起一个临时名字(t),这样外层查询才能引用它。这是 SQL 的语法要求,不能省略。你可以把 t 改成任何你想要的名字,比如 tmp、sub、a、去重结果 等