我的查询正确吗?我可以优化它吗?整数的正和负

时间:2019-03-30 11:36:21

标签: sql sql-server

我有两种解决方案,可以找到正整数和负整数的总和。请告诉哪个更正确,更优化? 还是还有其他更优化,更正确的查询? 问:

考虑表A的col1及以下值。

col1

20
-20
40
-40
-30
30

我需要下面的输出

POSITIVE_SUM    NEGATIVE_SUM

90               -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;

/ 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;


    POSITIVE_SUM    NEGATIVE_SUM

    90                  -90


2 个答案:

答案 0 :(得分:3)

我想知道您是如何提出第一个解决方案的:
-自联接(两次)表,
-每次产生6(相同)行,最后通过distinct得到1行,
-然后交叉加入2个结果。
我准备了demo,以便您看到导致第一个解决方案结果的步骤。
我不知道是否可以通过任何方式对其进行优化,
但是否有可能像第二种解决方案那样用条件聚合击败表的单次扫描?
我不这么认为。

答案 1 :(得分:2)

第二个查询不仅性能更好,而且返回正确的值。如果您运行第一个查询,则会看到它返回多行。

我认为对于第一个查询,您正在寻找类似的东西:

select p.positive_sum, n.negative_sum
from (select sum(col1) as positive_sum from a1 where col1 > 0) p cross join
     (select sum(col1) as negative_sum from a1 where col1 < 0) n

您要问的case表达式要比where快。

您缺少的是该版本需要扫描表两次。读取数据通常比数据元素上的任何功能都要昂贵。

有时第二个查询的性能可能非常相似。我可以想到三种情况。首先是col1上有聚集索引。其次是将col1用作分区键。第三是关于非常少量的数据(例如,适合单个数据页面的数据)。