问题
This is my approach:
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
The query returns output like this:
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
I only want to get rows where a6
is NOT NULL
. Other rows shall be filtered.
Desired output:
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
How to best achieve this?
回答1:
Add a HAVING clause:
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;
But first drop the redundant, expensive DISTINCT
. Rows are bound to be distinct after GROUP BY
has been applied. Also don't confuse DISTINCT (invoice_no)
with DISTINCT ON (invoice_no)
. The first one has misleading parentheses that are stripped away. The second one has different meaning. See:
- Select first row in each GROUP BY group?
Also using the modern, faster FILTER
clause for your conditional aggregates. See:
- How can I simplify this game statistics query?
回答2:
If you want to filter null values you can put AND a6 IS NOT NULL
in your WHERE condition
回答3:
add HAVING a6 IS NOT NULL
after the group by. So the query would become
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
来源:https://stackoverflow.com/questions/53675941/skip-whole-row-if-aggregated-value-is-null