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
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')
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.
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 .