嵌套SQL查询获取最高销售额分支名称出错,求正确写法
嵌套查询获取销售额最高分支名称的问题解决
表结构信息
employee表(记录员工所属分支)
| 员工ID(emp_id) | 分支ID(branch_id) |
|---|---|
| 100 | 1 |
| 101 | 1 |
| 102 | 2 |
| 103 | 2 |
| 104 | 2 |
| 105 | 2 |
| 106 | 3 |
| 107 | 3 |
| 108 | 3 |
works_with表(记录员工销售额)
| 员工ID(emp_id) | 总销售额(total_sales) |
|---|---|
| 102 | 267000 |
| 102 | 15000 |
| 105 | 55000 |
| 105 | 33000 |
| 105 | 130000 |
| 107 | 5000 |
| 107 | 26000 |
| 108 | 22500 |
| 108 | 12000 |
branch表(记录分支ID与名称对应关系)
| 分支ID(branch_id) | 分支名称(branch_name) |
|---|---|
| 1 | Corporate |
| 2 | Scranton |
| 3 | Stamford |
现有查询尝试
1. 查询各分支销售额
SELECT e.branch_id, SUM(w.total_sales) FROM employee e LEFT JOIN works_with w ON e.emp_id = w.emp_id GROUP BY e.branch_id ORDER BY SUM(w.total_sales) DESC;
查询结果:分支ID为2的销售额最高(500000),分支ID为3的销售额为65500,分支ID为1无销售额。
2. 获取最高销售额分支ID
SELECT e.branch_id FROM employee e LEFT JOIN works_with w ON e.emp_id = w.emp_id GROUP BY e.branch_id ORDER BY SUM(w.total_sales) DESC LIMIT 1;
该语句正确返回分支ID为2。
3. 失败的嵌套查询写法
SELECT branch_name FROM branch WHERE branch_id IN ( SELECT e.branch_id FROM employee e LEFT JOIN works_with w ON e.emp_id = w.emp_id GROUP BY e.branch_id ORDER BY SUM(w.total_sales) DESC ) LIMIT 1;
返回结果为Corporate而非正确的Scranton。原因是IN子句会忽略子查询中的ORDER BY排序,且外层的LIMIT 1是按照branch表的默认存储顺序取第一条记录(即branch_id=1的Corporate)。
正确的嵌套查询写法
方式一:子查询添加LIMIT 1
将LIMIT 1移入子查询,确保IN子句仅获取销售额最高的分支ID:
SELECT branch_name FROM branch WHERE branch_id IN ( SELECT e.branch_id FROM employee e LEFT JOIN works_with w ON e.emp_id = w.emp_id GROUP BY e.branch_id ORDER BY SUM(w.total_sales) DESC LIMIT 1 );
此方法仅返回单个最高销售额分支,若存在多个分支销售额并列最高,只会取其中一个。
方式二:匹配最高销售额(支持并列场景)
先计算所有分支的销售额,再找到最大值,关联获取对应分支名称:
SELECT b.branch_name FROM branch b JOIN ( SELECT e.branch_id, SUM(w.total_sales) AS total_sales FROM employee e LEFT JOIN works_with w ON e.emp_id = w.emp_id GROUP BY e.branch_id ) branch_sales ON b.branch_id = branch_sales.branch_id WHERE branch_sales.total_sales = ( SELECT MAX(total_sales) FROM ( SELECT SUM(w.total_sales) AS total_sales FROM employee e LEFT JOIN works_with w ON e.emp_id = w.emp_id GROUP BY e.branch_id ) sales );
若有多个分支销售额并列最高,此方法会返回所有符合条件的分支名称。
方式三:使用窗口函数(适用于MySQL 8+、PostgreSQL等)
利用窗口函数对分支销售额排名,直接取排名第一的分支:
SELECT branch_name FROM ( SELECT b.branch_name, SUM(w.total_sales) AS total_sales, RANK() OVER(ORDER BY SUM(w.total_sales) DESC) AS sales_rank FROM employee e LEFT JOIN works_with w ON e.emp_id = w.emp_id JOIN branch b ON e.branch_id = b.branch_id GROUP BY b.branch_id, b.branch_name ) ranked_branches WHERE sales_rank = 1;
此方法同样支持并列最高的场景,且代码结构更清晰。
内容的提问来源于stack exchange,提问作者Aspiring Guy
相关产品推荐
相关产品推荐

