SQL子查询结果重复显示而非NULL问题咨询
SQL子查询结果重复显示问题解析
问题现象
执行以下SQL查询时,result列的2500本应仅显示一次,却在每行重复出现:
查询代码
select sum(Importe) as Nuevo, (SELECT SUM(e.importe) FROM ext a WHERE (a.stat = 14 OR a.stat = 15) AND a.cvl_cliente = rmc.code GROUP BY rmc.num ) AS result FROM red rmc where rmc.code='7934628' group by num
执行结果
| Nuevo | Result |
|---|---|
| 2000 | 2500 |
| 100 | 2500 |
单独执行子查询
SELECT SUM(e.importe) FROM ext a WHERE (a.stat = 14 OR a.stat = 15) AND a.cvl_cliente =rmc.code GROUP BY rmc.num
返回结果:
| a |
|---|
| 2500 |
单独执行主查询部分
select sum(Importe) as Nuevo FROM red rmc where rmc.code='7934628' group by num
返回结果:
| Nuevo |
|---|
| 2000 |
| 100 |
疑问:单独执行子查询返回1条结果,主查询返回2条结果,为何合并后result列重复显示而非NULL?
原因分析
你的子查询是相关子查询,会跟着主查询的每一行执行一次:
- 主查询中
rmc.code固定为7934628,所以子查询的条件a.cvl_cliente = rmc.code每次都匹配同一个客户的所有符合条件的数据,求和结果始终是2500。 - 子查询里的
GROUP BY rmc.num实际无效——rmc是主查询的表,子查询引用主查询的分组字段num,相当于每行都按当前行的num分组,但子查询本身没有关联num的条件,最终还是返回该客户的总求和值。 - 只要子查询能找到匹配的数据,就会返回求和结果,不会返回
NULL,因此主查询每行都会显示这个相同的2500。
解决方案
根据你的需求,提供三种修正方案:
方案1:仅在第一行显示result,其余行显示NULL
如果希望result只在主查询的第一行显示,其他行显示NULL,可以用窗口函数标记行号:
select sum(Importe) as Nuevo, CASE WHEN ROW_NUMBER() OVER (ORDER BY num) = 1 THEN (SELECT SUM(a.importe) FROM ext a WHERE (a.stat = 14 OR a.stat = 15) AND a.cvl_cliente = rmc.code) ELSE NULL END AS result FROM red rmc where rmc.code='7934628' group by num
方案2:让result与主查询的num关联(返回对应num的求和值)
如果result应该是对应num的求和结果,需要在子查询中添加num的关联条件(假设ext表存在num字段):
select sum(Importe) as Nuevo, (SELECT SUM(a.importe) FROM ext a WHERE (a.stat = 14 OR a.stat = 15) AND a.cvl_cliente = rmc.code AND a.num = rmc.num ) AS result FROM red rmc where rmc.code='7934628' group by num
此时,若ext表中某个num没有匹配数据,result会显示NULL。
方案3:将子查询改为非相关子查询(所有行显示同一result)
如果接受所有行显示同一result,可以把子查询改为非相关子查询,避免重复执行:
select sum(Importe) as Nuevo, (SELECT SUM(a.importe) FROM ext a WHERE (a.stat = 14 OR a.stat = 15) AND a.cvl_cliente = '7934628' ) AS result FROM red rmc where rmc.code='7934628' group by num
内容的提问来源于stack exchange,提问作者Rubius
相关产品推荐
相关产品推荐

