Array integer []: comment obtenir toutes les valeurs distinctes dans une table et les compter?

9

Je ne suis pas si bon avec SQL (PostgreSQL). Voici ce que je veux faire:

J'ai une table, des champs:

id SERIAL
inet INET
ports integer[]

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

Comment puis-je

  1. obtenir toutes les valeurs de "ports" utilisées dans ce tableau: 80, 12
  2. compter le nombre d'adresses inet sur un port spécifique:

Comme ça:

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

Si quelqu'un en recherche une version 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
la source

Réponses:

12

Vous pouvez utiliser UNNEST.

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

L'utilisation de plusieurs UNNEST dans la même requête (ou la même liste de sélection, de toute façon) est source de confusion et est probablement préférable d'éviter.

jjanes
la source
4

Il est plus propre d'utiliser les fonctions de retour d'ensemble dans la FROMclause lorsque cela est possible. Le standard SQL ne les autorise pas dans la SELECTliste. Et c'est presque toujours possible puisque nous avons des LATERALjointures.

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

Mais je dois admettre que la variante "rapide et sale" @Jeff fournie est généralement plus rapide .

Erwin Brandstetter
la source