如果汇总值为null,则跳过整行

时间:2018-12-07 19:46:10

标签: sql postgresql aggregate having-clause

这是我的方法:

select distinct (invoice_no) as no,sum(total),
                sum(case when department_id=2 then total end) as a2,
                sum(case when department_id=3 then total end) as a3,
                sum(case when department_id=4 then total end) as a4,
                sum(case when department_id=5 then total end) as a5,
                sum(case when department_id=6 then total end) as a6
from article_sale
where  invoice_date = '2018-10-01' group by no order by no ASC

查询返回如下输出:

no      sum a2      a3    a4    a5      a6
68630   690 NULL    75    404   NULL    210.8
68631   0   NULL    NULL  NULL  NULL    NULL
68632   132 NULL    45    87    NULL    NULL
68633   75  NULL    75    NULL  NULL    NULL
68634   523 NULL    130   NULL  NULL    392.55
68635   0   NULL    NULL  NULL  NULL    NULL
68636   310 NULL    NULL  218   NULL    91.91
68637   273 NULL    NULL  NULL  NULL    273.24
68638   0   NULL    NULL  NULL  NULL    NULL

我只想获取a6NOT NULL的行。其他行应过滤。
所需的输出:

no      sum a2      a3    a4    a5      a6
68630   690 NULL    75    404   NULL    210.8
68634   523 NULL    130   NULL  NULL    392.55
68636   310 NULL    NULL  218   NULL    91.91
68637   273 NULL    NULL  NULL  NULL    273.24

如何最好地实现这一目标?

3 个答案:

答案 0 :(得分:3)

添加一个HAVING子句:

SELECT invoice_no                                  AS no
     , sum(total)                                  AS sum_total
     , sum(total) FILTER (WHERE department_id = 2) AS a2
     , sum(total) FILTER (WHERE department_id = 3) AS a3
     , sum(total) FILTER (WHERE department_id = 4) AS a4
     , sum(total) FILTER (WHERE department_id = 5) AS a5
     , sum(total) FILTER (WHERE department_id = 6) AS a6
FROM   article_sale
WHERE  invoice_date = '2018-10-01'
GROUP  BY 1
HAVING sum(total) FILTER (WHERE department_id = 6) IS NOT NULL
ORDER  BY 1;

但是首先删除冗余的,昂贵的DISTINCT。在应用GROUP BY之后,行必然是不同的。也不要将DISTINCT (invoice_no)DISTINCT ON (invoice_no)混淆。第一个被误导的括号被删除了。第二个有不同的含义。参见:

还对条件聚合使用更快的现代FILTER子句。参见:

答案 1 :(得分:1)

如果要过滤空值,可以将AND a6 IS NOT NULL置于WHERE条件下

答案 2 :(得分:1)

在分组依据之后添加HAVING a6 IS NOT NULL。这样查询就会变成

select distinct (invoice_no) as no,sum(total), 
sum(case when department_id=2 then total end) as a2, 
sum(case when department_id=3 then total end) as a3, sum(case when department_id=4 then total end) as a4, 
sum(case when department_id=5 then total end) as a5, 
sum(case when department_id=6 then total end) as a6 from article_sale where invoice_date = '2018-10-01' 
group by no having sum(case when department_id=6 then total end) is not null order by no ASC