如果聚合值为空,则跳过整行
Skip whole row if aggregated value is 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 order by no ASC
查询returns输出如下:
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
我只想获取 a6
为 NOT 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
如何最好地实现这一目标?
如果你想过滤空值,你可以在 WHERE 条件中加入 AND a6 IS NOT NULL
分组依据后加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
添加一个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)
。第一个有误导性的括号被去掉了。第二个有不同的含义。参见:
- Select first row in each GROUP BY group?
还为您的条件聚合使用现代的、更快的 FILTER
子句。参见:
- How can I simplify this game statistics query?
这是我的方法:
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
查询returns输出如下:
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
我只想获取 a6
为 NOT 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
如何最好地实现这一目标?
如果你想过滤空值,你可以在 WHERE 条件中加入 AND a6 IS NOT NULL
分组依据后加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
添加一个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)
。第一个有误导性的括号被去掉了。第二个有不同的含义。参见:
- Select first row in each GROUP BY group?
还为您的条件聚合使用现代的、更快的 FILTER
子句。参见:
- How can I simplify this game statistics query?