I have the following table
id | created_on | is_a | is_b | is_c
----------------------------------------------
1 | 01-02-1999 | True |False |False
2 | 23-05-1999 | False |True |False
3 | 25-08-2000 | False |True |False
4 | 30-07-2000 | False |False |True
5 | 05-09-2001 | False |False |True
6 | 05-09-2001 | False |True |False
7 | 05-09-2001 | True |False |False
8 | 05-09-2001 | True |False |False
In the table resulting the query, I would like to group by year of creation, and then be able to compare how many records were created in each year for is_a and is_b. I want to completely ignore from the count is_c.
count_a | count_b | by_creation_year
-----------------------------------------------
1 |1 | 1999
0 |1 | 2000
2 |1 | 2001
I tried the following query:
select count(is_a = True) a,
count(is_b = True) b,
date_trunc('year', created_on)
from cp_all
where is_c = False -- this removes the records where is_c is True
group by date_trunc('year', created_on)
order by date_trunc('year', created_on) asc;
But I get a table where the count of a and b is exactly the same.
Your count() argument evaluates to true or false which each gets counted as 1 regardless.
You want to use filter
select count(*) filter (where is_a) a,
count(*) filter (where is_b) b,
date_trunc('year', created_on)
from cp_all
where is_c = False -- this removes the records where is_c is True
group by date_trunc('year', created_on)
order by date_trunc('year', created_on) asc;
Doing it this way you will not need the where clause.
That's because count does not take boolean expressions it simply uses the expression and evaluates to check whether it is null or not null to add to the counter. So in this case you should use sum with case
select sum(case when is_a then 1 else 0 end) a,
sum(case when is_b then 1 else 0 end) b,
date_trunc('year', created_on)
from cp_all
where is_c = False -- this removes the records where is_c is True
group by date_trunc('year', created_on)
order by date_trunc('year', created_on) asc;
Although I like filter, this is simpler to type:
select sum(is_a::int) as a,
sum(is_b::int) as b,
date_trunc('year', created_on)
from cp_all
where is_c = False -- this removes the records where is_c is True
group by date_trunc('year', created_on)
order by date_trunc('year', created_on) asc;