简体   繁体   English

按年份和 boolean 列 postgres 分组

[英]group by year and boolean column postgres

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 .在产生查询的表中,我想按创建年份分组,然后能够比较is_ais_b每年创建的记录数。 I want to completely ignore from the count is_c .我想完全忽略计数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.但我得到一张表,其中 a 和 b 的计数完全相同。

Your count() argument evaluates to true or false which each gets counted as 1 regardless.您的count()参数评估为truefalse ,无论哪个都被计为1

You want to use filter你想使用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.这样做你将不需要where子句。

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.这是因为count不采用 boolean 表达式,它只是使用表达式并评估它是否是nullnot null添加到计数器。 So in this case you should use sum with case所以在这种情况下,你应该使用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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM