Проверьте, существует ли значение в массиве Postgres

мне нужен способ проверить, существует ли значение в данном массиве. До сих пор я придумал что-то вроде этого

select '{1,2,3}'::int[] @> (ARRAY[]::int[] || value_variable::int)

но я продолжаю думать, что должен быть более простой способ, я просто не вижу его.

Edit: просто понял, что я могу это сделать

select '{1,2,3}'::int[] @> ARRAY[value_variable::int]

это гораздо лучше, и я думаю, будет достаточно, но если у вас есть другие способы сделать это, пожалуйста, поделитесь.

5 ответов


проще с ANY построить:

SELECT value_variable = ANY ('{1,2,3}'::int[])

правый операнд ANY (между скобками) может быть либо set (результат подзапроса, например) или an массив. Есть несколько способов его использования:

важно отличия: массив операторы (<@, @> et al.) ожидал массив типы операндов и поддержка индексов GIN или GiST в стандартном дистрибутиве PostgreSQL, в то время как ANY строительство ожидает элемент введите как левый операнд и не поддерживает эти индексы. Пример:

ничего из этого не работает для NULL элементы. Для проверки NULL:


следите за эту ловушку я попал, при проверке, если определенное значение отсутствует в массиве, вы не должны делать:

SELECT value_variable != ANY('{1,2,3}'::int[])

но использовать

SELECT value_variable != ALL('{1,2,3}'::int[])

вместо.


но если у вас есть другие способы сделать это, пожалуйста, поделитесь.

вы можете сравнить два массива. Если какое-либо из значений в левом массиве перекрывает значения в правом массиве, то оно возвращает true. Это немного банально, но работает.

SELECT '{1}'   && '{1,2,3}'::int[];  -- true
SELECT '{1,4}' && '{1,2,3}'::int[];  -- true
SELECT '{4}'   && '{1,2,3}'::int[];  -- false
  • в первом и втором запросах value 1 находится в правом массиве
  • обратите внимание, что второй запрос true, хотя значение 4 не содержится в нужном массив
  • для третьего запроса нет значений в левом массиве (т. е. 4) находятся в правом массиве, поэтому он возвращает false

unnest можно использовать также. Он расширяет массив до набора строк, а затем просто проверяет, существует ли значение или нет, так же просто, как использовать IN или NOT IN.

например

  1. id => uuid

  2. exception_list_ids => uuid[]

select * from table where id NOT IN (select unnest(exception_list_ids) from table2)


при поиске существования элемента в массиве требуется правильное литье для передачи синтаксического анализатора SQL postgres. Вот один пример запроса с использованием оператора array contains в предложении join:

для простоты я перечисляю только главное:

table1 other_name text[]; -- is an array of text

показанная часть соединения SQL

from table1 t1 join table2 t2 on t1.other_name::text[] @> ARRAY[t2.panel::text]

и работает

on t2.panel = ANY(t1.other_name)

Я просто предполагаю, что дополнительное литье требуется, потому что синтаксический анализ не должен приносить определение таблицы для определения точного типа столбца. Другие, пожалуйста, прокомментируйте это.