假设有一个表,其中包含名为binary_value
,name
和created_at
的列以及id
列。
以下是此问题的SQL小提琴:http://sqlfiddle.com/#!15/d15d1/36
要获得如下所示的结果,什么是有效的查询?
ones_count | zeros_count | total
3 | 1 | 4
到目前为止,我有:
with cte2(count_type, counted) as (
with cte as (
select binary_value,
sum(case when binary_value = 1 then 1 else 0 end) as ones_count,
sum(case when binary_value = 0 then 1 else 0 end) as zeros_count
from infos
where name = 'me'
and created_at >= '2020-03-10 21:13:01.319677'
and created_at <= '2020-03-10 21:13:01.619677'
group by binary_value
)
select 'ones_count', ones_count from cte where binary_value = 1
union
select 'ones_count', zeros_count from cte where binary_value = 0
union
select 'total', sum(ones_count + zeros_count) as total from cte
)
select * from cte2;
以列形式给出:
count_type | counted
ones_count | 1
total | 4
ones_count | 3
如何连续获取结果?也许有一种与通用表表达式完全不同的方法?我开始看一下交叉表,它是postgres特有的,所以想知道这是否太矫kill过正。
这里也包含DDL和数据:
create table infos (
id serial primary key,
name character varying not null,
binary_value integer not null,
created_at timestamp without time zone not null
)
insert into infos ("binary_value", "name", "created_at") values
(1, 'me', '2020-03-10 21:13:01.319677'),
(1, 'me', '2020-03-10 21:13:01.419677'),
(0, 'me', '2020-03-10 21:13:01.519677'),
(1, 'me', '2020-03-10 21:13:01.619677');
答案 0 :(得分:1)
我认为您只需要条件聚合:
select count(*) filter (where binary_value = 0) as num_0s,
count(*) filter (where binary_value = 1) as num_1s,
count(*)
from infos
where name = 'me' and
created_at >= '2020-03-10 21:13:01.319677' and
created_at <= '2020-03-10 21:13:01.619677';
日期比较看起来很具体。我认为您确实打算在那儿设个范围。
Here是一个SQL提琴。
注意:如果您确实使用的是Postgres 9.3,则不能使用filter
子句(alas)。相反:
select sum( (binary_value = 0)::int ) as num_0s,
sum( (binary_value = 1)::int ) as num_1s,
count(*)
from infos
where name = 'me' and
created_at >= '2020-03-10 21:13:01.319677' and
created_at <= '2020-03-10 21:13:01.619677';
此外,如果您希望将结果分成三行,则更简单的查询是:
select binary_value, count(*)
from infos
where name = 'me' and
created_at >= '2020-03-10 21:13:01.319677' and
created_at <= '2020-03-10 21:13:01.619677'
group by grouping sets ( (binary_value), () );
答案 1 :(得分:0)
简单得多:
select
sum(case when binary_value = 1 then 1 else 0 end) as ones_count,
sum(case when binary_value = 0 then 1 else 0 end) as zeroes_count,
count(*) as total
from infos