Массив целое []: как получить все различные значения в таблице и подсчитать их?

9

Я не очень хорошо с SQL (PostgreSQL). Вот что я хочу сделать:

У меня есть таблица, поля:

id SERIAL
inet INET
ports integer[]

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

Как я могу

  1. получить все используемые значения "портов" в этой таблице: 80, 12
  2. посчитать, сколько адресов inet на конкретном порту:

Нравится:

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

Если кто-то ищет версию Django:

class Unnest(Func):
    function = 'UNNEST'

Model.objects \
.annotate(port=Unnest('ports', distinct=True)) \
.values('port') \
.annotate(count=Count('port')) \
.order_by('-count', '-port')
Сергей
источник

Ответы:

12

Вы можете использовать UNNEST.

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

Использование более одного UNNEST в одном и том же запросе (или, в любом случае, в одном и том же списке выбора) сбивает с толку и, вероятно, его лучше избегать.

jjanes
источник
4

По FROMвозможности лучше использовать возвращаемые функции в предложении. Стандарт SQL не допускает их в SELECTсписке. И это почти всегда возможно, так как у нас есть LATERALобъединения.

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

Но я должен признать, что «быстрый и грязный» вариант, предоставляемый @Jeff, обычно быстрее .

Эрвин Брандштеттер
источник