PostgreSQL-从条件聚合结果中删除NULLS行和列

时间:2018-11-09 08:27:47

标签: sql postgresql aggregate-functions

我使用条件聚合查询多维表

select A,
   SUM(case when D = 3 then D end) as SUM_D1,
   SUM(case when D = 4 then D end) as SUM_D2)

结果:

A    SUM_D1  SUM_D2
-------------------
a1   100     NULL
a1   200     NULL
a3   NULL    NULL
a4   NULL    NULL

但是,我想隐藏所有NULL行和列,如下所示:

A   SUM_D1 
-----------
a1   100 
a1   200 

我一直在寻找类似的问题,但这不是我期望的答案。

非常感谢您的帮助,

谢谢

4 个答案:

答案 0 :(得分:1)

出现空值是因为case statement不能处理的条件

select A,
   SUM(case when D = 3 then D end) as SUM_D1,
   SUM(case when D = 4 then D end) as SUM_D2
 from
    Table1
 group by
     A
 having 
     (case when D = 3 or D = 4 then D end) is not null

如评论所述,如果您想抑制null值。可以使用is not null

来抑制null。

答案 1 :(得分:1)

我可能对您的问题有误解,因为解决方案看起来很简单:

select A,
   SUM(case when D = 3 then D end) as SUM_D1,
   SUM(case when D = 4 then D end) as SUM_D2)
where D is not null

这不是您想要的,是吗? :-)

答案 2 :(得分:1)

我认为这可以满足您的要求

select A,
       coalesce(sum(case when D = 3 then D end),
                sum(case when D = 4 then D end)
               ) as sum_d
from t
group by A
having sum(case when d in (3, 4) then 1 else 0 end) > 0;

请注意,这仅返回一列-如您的示例。如果数据中同时包含“ 3”和“ 4”,则该值代表“ 3”。

如果要查询返回可变数量的列,则需要使用动态SQL或其他方法。 SQL查询返回固定数量的列。

一种方法是将值作为数组返回:

select a,
       array_agg(d order by d) as ds,
       array_agg(sumd order by d) as sumds
from (select a, d, sum(d) as sumd
      from t
      where d in (3, 4)
      group by a, d
     ) d
group by a;

答案 3 :(得分:1)

要过滤全空行,可以使用HAVING

select *
from 
 (
    select A,
       SUM(case when D = 3 then D end) as SUM_D1,
       SUM(case when D = 4 then D end) as SUM_D2)
    ...
 ) as dt
where SUM_D1 is not null 
  and SUM_D2 is not null

当然,如果您有简单的条件(如示例中的条件),则最好在聚合之前 进行过滤:

select A,
   SUM(case when D = 3 then D end) as SUM_D1,
   SUM(case when D = 4 then D end) as SUM_D2)
...
where D in (3,4)

现在至少有一个计算将返回一个值,因此无需检查全空。

要过滤全空列,您需要一些动态SQL:

  • 使用“插入/选择”在临时选项卡中实现数据
  • 扫描每列以查找全空select 1 from temp having count(SUM_D1) > 0
  • 基于此动态创建选择列表
  • 运行选择

但是您为什么认为您需要这个?用户运行相同的存储过程并为每次运行接收不同数量的列会造成混乱。