PostgreSQL 合并 COUNT 和 GROUP BY 结果
PostgreSQL merge COUNT and GROUP BY result
select type, created_at::date , count(type)
from txns
group by created_at::date, type
order by created_at::date;
上面的 SQL 查询给出了以下输出:
type | created_at | count
---------+------------+-------
full | 2017-05-20 | 2
virtual | 2017-05-20 | 2
full | 2017-05-21 | 1
virtual | 2017-05-21 | 1
full | 2017-05-22 | 3
如何将上述结果按 created_at
分组以获得以下输出:
created_at | full_count | virtual_count
------------+-----------------
2017-05-20 | 2 | 2
2017-05-21 | 1 | 1
2017-05-22 | 3 | 0
我想在一行中按 created_at
计算 full
和 virtual
类型。
这应该有效:
with so as (
select type, created_at::date , count(type) from txns group by created_at::date, type order by created_at::date
)
select
created_at
, sum(case when type = 'full' then count else 0 end) full_count
, sum(case when type = 'virtual' then count else 0 end) virtual_count
from so
group by created_at;
created_at | full_count | virtual_count
------------+------------+---------------
2017-05-20 | 2 | 2
2017-05-21 | 1 | 1
2017-05-22 | 3 | 0
(3 rows)
如果你有两个以上的类型,在进一步处理中你可以处理hstore:
WITH q AS ( SELECT type, created_at::date , count(type) FROM txns GROUP BY 1,2)
SELECT created_at, hstore(array_agg(type), array_agg(count::text))
FROM q GROUP BY 1;
我会在没有 CTE/subquery 的情况下这样做:
select created_at::date,
sum( (type = 'Full')::int ) as cnt_full,
sum( (type = 'Virtual')::int ) as cnt_virtual
from txns
group by created_at::date
order by created_at::date;
Postgres 经常具体化 CTE,因此这甚至可能具有轻微的性能优势。
注意:您还可以在较新版本的 Postgres 中使用 filter
:
select created_at::date,
count(*) filter (where type = 'Full') as cnt_full,
count(*) filter (where type = 'Virtual') as cnt_Virtual
from txns
group by created_at::date
order by created_at::date;
select type, created_at::date , count(type)
from txns
group by created_at::date, type
order by created_at::date;
上面的 SQL 查询给出了以下输出:
type | created_at | count
---------+------------+-------
full | 2017-05-20 | 2
virtual | 2017-05-20 | 2
full | 2017-05-21 | 1
virtual | 2017-05-21 | 1
full | 2017-05-22 | 3
如何将上述结果按 created_at
分组以获得以下输出:
created_at | full_count | virtual_count
------------+-----------------
2017-05-20 | 2 | 2
2017-05-21 | 1 | 1
2017-05-22 | 3 | 0
我想在一行中按 created_at
计算 full
和 virtual
类型。
这应该有效:
with so as (
select type, created_at::date , count(type) from txns group by created_at::date, type order by created_at::date
)
select
created_at
, sum(case when type = 'full' then count else 0 end) full_count
, sum(case when type = 'virtual' then count else 0 end) virtual_count
from so
group by created_at;
created_at | full_count | virtual_count
------------+------------+---------------
2017-05-20 | 2 | 2
2017-05-21 | 1 | 1
2017-05-22 | 3 | 0
(3 rows)
如果你有两个以上的类型,在进一步处理中你可以处理hstore:
WITH q AS ( SELECT type, created_at::date , count(type) FROM txns GROUP BY 1,2)
SELECT created_at, hstore(array_agg(type), array_agg(count::text))
FROM q GROUP BY 1;
我会在没有 CTE/subquery 的情况下这样做:
select created_at::date,
sum( (type = 'Full')::int ) as cnt_full,
sum( (type = 'Virtual')::int ) as cnt_virtual
from txns
group by created_at::date
order by created_at::date;
Postgres 经常具体化 CTE,因此这甚至可能具有轻微的性能优势。
注意:您还可以在较新版本的 Postgres 中使用 filter
:
select created_at::date,
count(*) filter (where type = 'Full') as cnt_full,
count(*) filter (where type = 'Virtual') as cnt_Virtual
from txns
group by created_at::date
order by created_at::date;