web-dev-qa-db-fra.com

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

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 cherche une version Django de celui-ci:

class Unnest(Func):
    function = 'UNNEST'

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

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.

12
jjanes

Il est plus propre d'utiliser les fonctions set return dans la clause FROM dans la mesure du possible. Le standard SQL ne les autorise pas dans la liste SELECT. Et c'est presque toujours possible car nous avons LATERAL jointures.

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 fourni est généralement plus rapide .

4
Erwin Brandstetter