You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL查询正确性与优化咨询:正负整数求和方案对比

正负数分组求和的SQL方案对比与优化建议

先聊聊你的场景:表A的col1列存着20, -20, 40, -40, -30, 30这些数据,需要分别计算正数总和、负数总和,最终得到POSITIVE_SUM=90、NEGATIVE_SUM=-90的结果。咱们来拆解下你的两个方案:

方案q1的问题

select POSITIVE_SUM,NEGATIVE_SUM 
from (select distinct sum(a2.col1) AS "POSITIVE_SUM" 
      from A a1 join A a2 on a2.col1>0 group by a1.col1) t1 , 
     (select distinct sum(a2.col1) AS "NEGATIVE_SUM"
      from A a1 join A a2 on a2.col1<0 group by a1.col1) t2;

这个写法虽然能得到正确结果,但完全是绕了远路:

  • 你用了自连接逻辑,比如计算正数和时,a1的每一行都会和a2里的所有正数行做连接。假设表有6行、正数有3行,这会生成6*3=18条中间记录,之后还要按a1.col1分组,最后靠distinct去重才得到正确求和值——做了超多无意义的冗余操作!
  • 数据量小的时候看不出问题,一旦表的行数增多,这种自连接会爆炸式增加中间数据量,占用大量内存和CPU,性能会拉胯。

方案q2的优势

select sum (case when a1.col1 >= 0 then a1.col1 else 0 end) as positive_sum, 
       sum (case when a1.col1 < 0 then a1.col1 else 0 end) as negative_sum 
from A a1;

这个才是标准且高效的写法:

  • 只需要扫描表一次,用case when在sum函数里做条件判断,直接累加符合要求的数值,不符合的用0代替(不会影响求和结果)。
  • 逻辑清晰直白,没有多余的连接、分组或去重操作,性能拉满,不管数据量大小都能稳定高效运行。

有没有更简洁的替代写法?

其实q2已经是最优逻辑了,不过部分数据库支持更简洁的语法糖,比如:

  • PostgreSQL可以用filter子句简化:
    select sum(col1) filter (where col1 >= 0) as positive_sum,
           sum(col1) filter (where col1 < 0) as negative_sum
    from A;
    
  • MySQL 8.0+或SQL Server可以用IIF函数替代case when:
    select sum(IIF(col1 >= 0, col1, 0)) as positive_sum,
           sum(IIF(col1 < 0, col1, 0)) as negative_sum
    from A;
    

这些写法本质和q2的逻辑完全一致,性能也差不多,只是写法更简洁,具体用哪种看你使用的数据库。

另外要注意:你的q2里把0归到了正数总和里,如果后续需求里0需要单独统计,只需要调整case when的条件即可(比如改成col1 > 0和col1 < 0,再加一个sum(case when col1=0 then col1 else 0 end) as zero_sum)。

内容的提问来源于stack exchange,提问作者suhas_patil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:40:44