Array integer []: ¿cómo obtener todos los valores distintos en una tabla y contarlos?

9

No soy tan bueno con SQL (PostgreSQL). Esto es lo que quiero hacer:

Tengo una tabla, campos:

id SERIAL
inet INET
ports integer[]

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

Cómo puedo

  1. obtenga todos los valores de "puertos" usados ​​en esta tabla: 80, 12
  2. cuente cuántas direcciones inet hay en un puerto específico:

Me gusta esto:

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

Si alguien está buscando una versión de 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
fuente

Respuestas:

12

Puedes usar UNNEST.

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

Usar más de un UNNEST en la misma consulta (o la misma lista de selección, de todos modos) es confuso y probablemente sea mejor evitarlo.

jjanes
fuente
4

Es más limpio usar funciones de retorno de conjunto en la FROMcláusula donde sea posible. El estándar SQL no los permite en la SELECTlista. Y casi siempre es posible ya que tenemos LATERALuniones.

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

Pero debo admitir que la variante "rápida y sucia" que proporcionó @Jeff suele ser más rápida .

Erwin Brandstetter
fuente