Matriz número inteiro []: como obter todos os valores distintos em uma tabela e contá-los?

9

Eu não sou tão bom com SQL (PostgreSQL). Aqui está o que eu quero fazer:

Eu tenho uma tabela, campos:

id SERIAL
inet INET
ports integer[]

 id |    inet    | ports 
----+------------+------------
  2 | 1.2.2.1    | {80}
  1 | 1.2.3.4    | {80,12}
  ...

Como posso

  1. obtenha todos os valores de "portas" usados ​​nesta tabela: 80, 12
  2. conte quantos endereços inet estão em uma porta específica:

Como isso:

  port  | count
--------+------------
 12     | 1
 80     | 2
  ...

Se alguém estiver procurando por uma versão do Django:

class Unnest(Func):
    function = 'UNNEST'

Model.objects \
.annotate(port=Unnest('ports', distinct=True)) \
.values('port') \
.annotate(count=Count('port')) \
.order_by('-count', '-port')
Sergey
fonte

Respostas:

12

Você pode usar UNNEST.

select unnest(ports) as port, count(*) from foo group by port;

O uso de mais de um UNNEST na mesma consulta (ou na mesma lista de seleção) é confuso e provavelmente é melhor evitar.

jjanes
fonte
4

É mais limpo usar funções de retorno definidas na FROMcláusula sempre que possível. O padrão SQL não os permite na SELECTlista. E é quase sempre possível, pois temos LATERALjunções.

SELECT port, count(*) AS ct
FROM   tbl t, unnest(t.ports) AS port  -- implicit LATERAL join
GROUP  BY port;

Mas tenho que admitir que a variante "rápida e suja" @Jeff fornecida é normalmente mais rápida .

Erwin Brandstetter
fonte