PostgreSQL数组中统计例子
Contents
问题
这个问题,是在一个PG群里有群友问到的。如下:
请教个问题
有个表 temp
数据如下(ids为array类型)
ids no
{1,2} 10
{1,3} 20
{2,3} 30
现在希望得到这样的结果
id no
1 30
2 40
3 50
这个group by应该怎么写?
建表
create table tep (ids int[], no int);
插入示例数据
insert into tep values (array[1,2], 10);
insert into tep values (array[1,3], 20);
insert into tep values (array[2,3], 30);
SQL
解决思路:因为他想要的是:
1=10+20
2=10+30
3=20+30
所以,可以将数组中的元素,拆分成行,然后group by 一下id, sum(no),就可以了,即:
yang=# with cte as (select unnest(ids) as id, no from tep) select id, sum(no) from cte group by id order by id asc;
id | sum
----+-----
1 | 30
2 | 40
3 | 50
(3 rows)
yang=#
或
yang=# select unnest(ids) as id, sum(no) from tep group by id order by id asc;
id | sum
----+-----
1 | 30
2 | 40
3 | 50
(3 rows)
yang=#
不知道为什么,总喜欢使用CTE来做.感觉这样子更清晰点,哈哈.
使用CTE,无索引的情况,与不使用CTE对比.
yang=# explain analyze verbose with cte as (select unnest(ids) as id, no from tep) select id, sum(no) from cte group by id order by id asc;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------
Sort (cost=306537.78..306538.28 rows=200 width=8) (actual time=8093.771..8093.771 rows=7 loops=1)
Output: cte.id, (sum(cte.no))
Sort Key: cte.id
Sort Method: quicksort Memory: 25kB
CTE cte
-> Seq Scan on public.tep (cost=0.00..77148.14 rows=9175200 width=33) (actual time=0.076..3207.449 rows=7340032 loops=1)
Output: unnest(tep.ids), tep.no
-> HashAggregate (cost=229380.00..229382.00 rows=200 width=8) (actual time=8093.757..8093.759 rows=7 loops=1)
Output: cte.id, sum(cte.no)
Group Key: cte.id
-> CTE Scan on cte (cost=0.00..183504.00 rows=9175200 width=8) (actual time=0.082..5851.946 rows=7340032 loops=1)
Output: cte.id, cte.no
Planning time: 0.175 ms
Execution time: 8111.710 ms
(14 rows)
yang=# explain analyze verbose select unnest(ids) as id, sum(no) from tep group by id order by id asc;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------
Sort (cost=3659321.29..3659323.04 rows=700 width=33) (actual time=5276.652..5276.653 rows=7 loops=1)
Output: (unnest(ids)), (sum(no))
Sort Key: (unnest(tep.ids))
Sort Method: quicksort Memory: 25kB
-> HashAggregate (cost=3659284.66..3659288.21 rows=700 width=33) (actual time=5276.637..5276.639 rows=7 loops=1)
Output: (unnest(ids)), sum(no)
Group Key: unnest(tep.ids)
-> Seq Scan on public.tep (cost=0.00..1858440.66 rows=360168800 width=33) (actual time=0.052..3203.487 rows=7340032 loops=1)
Output: unnest(ids), no
Planning time: 0.212 ms
Execution time: 5276.723 ms
(11 rows)
yang=#
这情况下,不使用CTE好点.