Как проверить наличие значения в массиве PostgreSQL

Такая задача как проверка наличия определенного значения в массиве только кажется простой и однозначной. В PostgreSQL до версии 9.5 отсутствовала специальная функция для этих целей. Вы можете искать вхождение одного массива в другой, получать пересечение двух массивов и т.д., но не искать одиночное значение в массиве. Начиная с версии 9.5, такая функция присутствует.

Поиск элемента массива в PostgreSQL версии 9.5 и выше

Согласно официальной документации вы можете использовать функцию array_position.

Она вернет порядковый номер первого вхождения заданного значения в массиве, либо NULL, если оно не найдено. Соответственно, чтобы проверить, есть ли в массиве [‘first’, ‘second’, ‘third’] значение ‘findme’, можно поступить так:

array_position(ARRAY['first', 'second', 'third'] , 'findme') IS NOT NULL

Поиск элемента массива в PostgreSQL версии 9.4 и ниже

Самый простой способ сделать аналогичное в более старых версиях:

'findme' = ANY(ARRAY['first', 'second', 'third']::TEXT[]

Однако, если у вас на руках не массив, а подзапрос, то такой вариант работает не всегда. Если есть проблемы с ANY, то вам поможет следующий код:

SELECT * FROM some_table
WHERE ('findme' || ARRAY[]::TEXT[]) && (some_subselect_or_array_goes_here) ;

Вся эта конструкция создает массив из пустого массива нужного типа, добавляет в него искомое значение и находит, есть ли пересечение этого новосозданного массива с тем, в котором осуществляется поиск. Вы можете спросить, зачем нужен такой сложный код, как:

ARRAY[]::TEXT[]

Дело в том, что простой  TEXT[] вызвал бы ошибку, одиноко стоящий ARRAY[] тоже, потому что система не сможет определить тип массива автоматически, так что этот «грязный хак» здесь необходим.

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.