Array integer []: Wie werden alle unterschiedlichen Werte in einer Tabelle abgerufen und gezählt?

9

Ich bin nicht so gut mit SQL (PostgreSQL). Folgendes möchte ich tun:

Ich habe eine Tabelle, Felder:

id SERIAL
inet INET
ports integer[]

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

Wie kann ich

  1. Holen Sie sich alle verwendeten "Ports" -Werte in dieser Tabelle: 80, 12
  2. Zählen Sie, wie viele Inet-Adressen sich an einem bestimmten Port befinden:

So was:

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

Wenn jemand nach einer Django-Version sucht:

class Unnest(Func):
    function = 'UNNEST'

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

Antworten:

12

Sie können verwenden UNNEST.

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

Die Verwendung von mehr als einem UNNEST in derselben Abfrage (oder zumindest in derselben Auswahlliste) ist verwirrend und wird wahrscheinlich am besten vermieden.

jjanes
quelle
4

Es ist sauberer, FROMwenn möglich Set-Return-Funktionen in der Klausel zu verwenden. Der SQL-Standard erlaubt sie nicht in der SELECTListe. Und es ist fast immer möglich, seit wir LATERALJoins haben.

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

Aber ich muss zugeben, dass die bereitgestellte "Quick-and-Dirty" -Variante @Jeff normalerweise schneller ist .

Erwin Brandstetter
quelle