PostgreSQL统计与其他列具有相同值的ID的其他值

PostgreSQL统计与其他列具有相同值的ID的其他值,postgresql,group-by,count,Postgresql,Group By,Count,假设下表存储了观察的id及其地址\u id。可以使用以下代码创建表: drop table if exists schema.pl_address_cnt; create table schema.pl_address_cnt ( id serial, address_id int); insert into schema.pl_address_cnt(address_id) values (100), (101), (100), (101), (100), (125), (

假设下表存储了观察的
id
及其
地址\u id
。可以使用以下代码创建表:

drop table if exists schema.pl_address_cnt;
create table schema.pl_address_cnt (
    id serial,
    address_id int);

insert into schema.pl_address_cnt(address_id) values 
(100), (101), (100), (101), (100), (125), (128), (200), (200), (100);
我的任务是计算每个
id
有多少其他
id
s(因此-1)具有相同的
地址\u id
。我想出了一个解决方案,结果证明在原始数据集上非常昂贵(
explain
)。我想知道我的解决方案是否能得到优化

with tmp_table as (select address_id
                        , count(distinct id) as id_count
                    from schema.pl_address_cnt
                    group by address_id
)
select id
    , id_count - 1
from schema.pl_address_cnt as pac
left join tmp_table as tt on tt.address_id=pac.address_id;

您可以尝试省略CTE,在公共地址但不同ID上进行自左连接,然后将其聚合

SELECT pac1.id,
       count(pac2.id)
       FROM pl_address_cnt pac1
            LEFT JOIN pl_address_cnt pac2
                      ON pac1.address_id = pac2.address_id
                         AND pac1.id <> pac2.id
       GROUP BY pac1.id
       ORDER BY pac1.id;
选择pac1.id,
计数(pac2.id)
来自pl_地址\u cnt pac1
左连接pl_地址\u cnt pac2
在pac1.address\u id=pac2.address\u id上
和pac1.id pac2.id
按pac1.id分组
按pac1.id订购;

为了提高性能,您可以在
(address\u id,id)
(id)
上尝试索引,谢谢您的评论。当我省略CTE并使用您的解决方案时,
explain analysis
返回的成本是我原始查询的3倍:(