在嵌套SELECT查询中如何避免使用别名并保留原列名?
问题描述
我有如下表格:
| id | area | name | value |
|---|---|---|---|
| 1 | A | abc | 1.2 |
| 2 | B | abc | 2.3 |
| 3 | C | def | 3.4 |
我可以通过以下SQL语句计算每个name对应的value总和:
SELECT name, SUM(value) AS "total" FROM table GROUP BY name;
执行后输出结果如下:
| name | total |
|---|---|
| abc | 3.5 |
| def | 3.4 |
现在我希望将上述total值作为计算列添加到原表中,期望输出如下:
| id | area | name | value | total |
|---|---|---|---|---|
| 1 | A | abc | 1.2 | 3.5 |
| 2 | B | abc | 2.3 | 3.5 |
| 3 | C | def | 3.4 | 3.4 |
我尝试将SELECT子查询作为列添加:
SELECT table.*, (SELECT SUM(value) AS "total" FROM table GROUP BY name) FROM table
但执行失败,报错:
Subquery returns more than 1 row
我明白原因:该子查询会返回所有name的总和,而非当前记录对应的name总和。于是我添加WHERE子句,限定仅查询当前name:
SELECT id, area, name AS current_name, value, (SELECT SUM(value) FROM table WHERE name=current_name GROUP BY name) AS "total" FROM table
该语句可以正常执行,但缺点是原name列被重命名为current_name。请问是否有办法避免使用别名,同时保留原列名?
解决方案
当然可以,你不需要给原name列重命名,直接通过表别名区分内外层表即可,这样能直接引用外层表的name字段:
SELECT t1.id, t1.area, t1.name, -- 保留原列名,无需重命名 t1.value, (SELECT SUM(t2.value) FROM table t2 WHERE t2.name = t1.name -- 通过表别名关联外层的name GROUP BY t2.name) AS "total" FROM table t1 -- 给外层表起别名t1
另外,更高效简洁的写法是使用窗口函数(适用于MySQL 8.0+、PostgreSQL、SQL Server等支持窗口函数的数据库),无需子查询即可实现需求:
SELECT id, area, name, value, SUM(value) OVER (PARTITION BY name) AS "total" FROM table;
窗口函数SUM(value) OVER (PARTITION BY name)会按name分组计算总和,并将结果对应到每一行,完全符合你的需求,且性能更优。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

