Array integer []: bagaimana cara mendapatkan semua nilai yang berbeda dalam sebuah tabel dan menghitungnya?

9

Saya tidak begitu baik dengan SQL (PostgreSQL). Inilah yang ingin saya lakukan:

Saya punya tabel, bidang:

id SERIAL
inet INET
ports integer[]

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

Bagaimana bisa saya

  1. dapatkan semua nilai "port" yang digunakan dalam tabel ini: 80, 12
  2. hitung berapa banyak alamat inet pada port spesifik:

Seperti ini:

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

Jika ada yang mencari versi Django itu:

class Unnest(Func):
    function = 'UNNEST'

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

Jawaban:

12

Anda bisa menggunakannya UNNEST.

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

Menggunakan lebih dari satu UNNEST dalam kueri yang sama (atau daftar pilih yang sama, bagaimanapun juga) membingungkan dan mungkin sebaiknya dihindari.

jjanes
sumber
4

Lebih bersih untuk menggunakan fungsi pengembalian set di FROMklausa jika memungkinkan. Standar SQL tidak memungkinkan mereka dalam SELECTdaftar. Dan hampir selalu mungkin karena kita sudah LATERALbergabung.

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

Tetapi saya harus mengakui bahwa varian "cepat dan kotor" @Jeff yang disediakan biasanya lebih cepat .

Erwin Brandstetter
sumber